How to UPDATE all columns of a record without having to list every column

后端 未结 8 1828
情歌与酒
情歌与酒 2020-12-29 03:20

I\'m trying to figure out a way to update a record without having to list every column name that needs to be updated.

For instance, it would be nice if I could use so

相关标签:
8条回答
  • 2020-12-29 03:53

    Here's a hardcore way to do it with SQL SERVER. Carefully consider security and integrity before you try it, though.

    This uses schema to get the names of all the columns and then puts together a big update statement to update all columns except ID column, which it uses to join the tables.

    This only works for a single column key, not composites.

    usage: EXEC UPDATE_ALL 'source_table','destination_table','id_column'

    CREATE PROCEDURE UPDATE_ALL
    
    @SOURCE VARCHAR(100),
    @DEST VARCHAR(100),
    @ID VARCHAR(100)
    
    AS
    
        DECLARE @SQL VARCHAR(MAX) =  
    
        'UPDATE D SET ' +
    
        -- Google 'for xml path stuff' This gets the rows from query results and 
        -- turns into comma separated list.
        STUFF((SELECT ', D.'+ COLUMN_NAME + ' = S.' + COLUMN_NAME
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = @DEST
        AND COLUMN_NAME <> @ID 
        FOR XML PATH('')),1,1,'')
    
        + ' FROM ' + @SOURCE + ' S JOIN ' + @DEST + ' D ON S.' +  @ID + ' = D.' + @ID
    
        --SELECT @SQL
        EXEC (@SQL)
    
    0 讨论(0)
  • 2020-12-29 03:53

    It is possible. Like npe said it's not a standard practice. But if you really have to:

    1. First a scalar function
    CREATE FUNCTION [dte].[getCleanUpdateQuery] (@pTableName varchar(40), @pQueryFirstPart VARCHAR(200) = '', @pQueryLastPart VARCHAR(200) = '', @pIncludeCurVal BIT = 1)
    RETURNS VARCHAR(8000) AS
    BEGIN
    DECLARE @pQuery VARCHAR(8000);
    WITH cte_Temp
    AS
    (
        SELECT
        C.name
        FROM SYS.COLUMNS AS C
            INNER JOIN SYS.TABLES AS T ON T.object_id = C.object_id
        WHERE T.name = @pTableName
    )
        SELECT @pQuery = (
        CASE @pIncludeCurVal
        WHEN 0 THEN
        (
        STUFF(
            (SELECT ', ' + name + ' = ' + @pQueryFirstPart + @pQueryLastPart FROM cte_Temp FOR XML PATH('')), 1, 2, ''
            )
        )
        ELSE
        (
        STUFF(
            (SELECT ', ' + name + ' = ' + @pQueryFirstPart + name +  @pQueryLastPart FROM cte_Temp FOR XML PATH('')), 1, 2, ''
            )
        ) END)
    
        RETURN 'UPDATE ' + @pTableName + ' SET ' + @pQuery
    END
    
    2. Use it like this
    DECLARE @pQuery VARCHAR(8000) = dte.getCleanUpdateQuery(<your table name>, <query part before current value>, <query part after current value>, <1 if current value is used. 0 if updating everything to a static value>);
    EXEC (@pQuery)
    
    Example 1: make all employees columns 'Unknown' (you need to make sure column type matches the intended value:
    DECLARE @pQuery VARCHAR(8000) = dte.getCleanUpdateQuery('employee', '', 'Unknown', 0);
    EXEC (@pQuery)
    
    Example 2: Remove an undesired text qualifier (e.g. #)
    DECLARE @pQuery VARCHAR(8000) = dte.getCleanUpdateQuery('employee', 'REPLACE(', ', ''#'', '''')', 1);
    EXEC (@pQuery)
    

    This query can be improved. This is just the one I saved and sometime I use. You get the idea.

    0 讨论(0)
提交回复
热议问题