使用表变量进行动态查询以循环遍历所有表以在数据库中更新

问题描述 投票:1回答:2

我正在研究SQL查询以更新数据库中的表和列列表。欢迎任何建议。

我使用的是information_schema.tables和information_schema.columns,查找表和表变量。但是,我正在更新问题。

我从连接开始,以确保我匹配查找表所需的正确表和列。

如果是table.column,我需要遍历并更新与objectname匹配的表。

我试图使用光标,但做了一些研究和思想表变量可能更好地优化和性能。我声明了我的变量并创建了一个表变量,但它仍然没有更新。在创建并填充表变量后,我从下面的查询开始。

我尝试了使用游标和表变量的不同方法,但我没有完成更新。

'Select l.objectname, l.fieldname, l.newpvalue, l.oldpvalue from lookup_table 1 inner join information_schema.tables t
                 on l.objectname = t.table_name
                inner join information_schema.columns c
                  on l.fieldname = c.column_name and l.objectname 
                                 = c.table_name'

这是我尝试参数化的新更新

SELECT 'UPDATE' + I.TABLE_NAME + 'SET C.COLUMN_NAME = 
                                        CASE 
                                            WHEN TP.[listValue] = TP.[OldValue]
                                            WHEN TP.[listValue] != TP.[OldValue] 
                                                        THEN SET TP.NOTES = C.COLUMN_NAME '-' TP.[OldValue]
                                                        AND SET C.COLUMN_NAME = NULL
                                        END
        FROM 
                INFORMATION_SCHEMA.TABLES I INNER JOIN [dbo].[tpRef] tp
                                    ON I.TABLE_NAME = tp.ObjectName
                                INNER JOIN INFORMATION_SCHEMA.COLUMNS C
                                    ON tp.[FieldName] = C.COLUMN_NAME
                                        AND tp.[ObjectName] = C.TABLE_NAME
                                LEFT JOIN INFORMATION_SCHEMA.COLUMNS C2
                                    ON tp.[FieldName] = C2.COLUMN_NAME
                                    AND C2.COLUMN_NAME = 'NOTES'
        WHERE TABLE_TYPE = 'base table'
                        AND tp.ObjectName = 'table name'
                        AND tp.FieldName = 'table field'
                        AND tp.[listValue] = 'List' 
tsql
2个回答
0
投票

不是一个工作游标,需要查询填写所需的列来填充变量。

declare 
     @table_name varchar(128) 
    ,@schema_name varchar(128) -- dbo is the default schema, if custom make sure query returns the correct schema
    ,@update_column varchar(128) 
    ,@update_data varchar(1024)
    ,@where_column varchar(128)
    ,@where_data varchar(1024)
    ,@s varchar(max);
declare x cursor local fast_forward 
for
/*
 insert your query returning desired values to be looped through.
 */
select 1,2,3,4,5,6 --6 variables to populate. delete this line when you get your query written above :)
open x;
fetch next from x into @table_name,@update_column,@schema_name,@update_data,@where_column,@where_data;

while @@fetch_status = 0
    begin
        set @s = '
            update ' + quotename(@schema_name) + '.' + quotename(@table_name) + ' 
            set  ' + quotename(@update_column) + ' = ''' + @update_data + ''' where ' + quotename(@where_column) + ' = ''' + @where_data + ''';
            '
        begin try
            --to execute it, you can use exec()
            exec(@s); 
            --to print out the string so you can read and or copy/paste to text execution use print()
            print(@s);
            /* 
                I would recommend print(@s); until you have all your bugs worked out.
                process the updates manually from the printed statements to verify syntax correctness and results
             */
        end try
        begin catch
            print error_message()
        end catch;
        -- this list of variables must match the first "fetch next" and all be declared and returned in the "for" query of the cursor.
        -- those that are not must be set inside the cursor by queries, calculations or hardcoded.
        fetch next from x into @table_name,@update_column,@schema_name,@update_data,@where_column,@where_data;
    end

close x;
deallocate x;

使用的光标是 Fast_forward(SO回答)=(read_only和forward_only)Local(游标性能细分)=范围内的本地,仅在范围内有效。

我仍然无法使用information_schema视图...


0
投票

我试图使用表变量,但是你是否指示同时使用表变量和游标?

当我跑下面需要很长时间。

----更新表和列找到

SELECT @STRUPDSQL =
         'UPDATE' + 'I.TABLE_NAME' + 'SET C.COLUMN_NAME = 
                                        CASE 
                                            WHEN TP.[PicklistValue] = TP.[OldValue]
                                            WHEN TP.[PicklistValue] != TP.[OldValue] 
                                                        THEN SET TP.NOTES = C.COLUMN_NAME - TP.[OldValue]
                                                        AND SET C.COLUMN_NAME = NULL
                                        END
        FROM 
                INFORMATION_SCHEMA.TABLES I INNER JOIN @TBLS T
                                            ON I.TABLE_NAME = T.v_TABLENAME

        WHERE T.v_TABLENAME =@l_TBLNM   AND T.v_COLUMNNAME =@l_COLNNM                   

'
    SET @I = @I + 1
    END

我有它的工作,但我想要更新的值被读取为列名而不是列数据值。

如果引号(@COLNAME)不是NULL

        BEGIN
            SET @SQL = 'UPDATE ' + quotename(@TABLENAME) + ' SET ' + quotename(@COLNAME) + ' = ' +'"' + @TVALUE + '"' + ' ' + 'WHERE ' + quotename(@COLNAME) + '= AccountSource'
        END
© www.soinside.com 2019 - 2024. All rights reserved.