更新从sys.columns和sys.tables中选择的表中的值

时间:2019-05-15 10:16:37

标签: sql sql-server

我们的一个用户ID已在数据库中的一个表中更新,但在其他63个表中未更新。我需要使用UserID列在所有其他表中更新此ID。

我已经设法从sys.tables和sys.columns中选择了所有需要的表,但我不是100%不确定如何更新这些表中的每个表的值。

我正在使用此查询选择表:

SELECT      c.name  AS 'ColumnName'
            ,t.name AS 'TableName'
FROM        sys.columns c
JOIN        sys.tables  t   ON c.object_id = t.object_id
WHERE       c.name LIKE '%UserID%'
ORDER BY    TableName
            ,ColumnName;

这给了我所有相关表和列名的列表。

我也修改了上面的查询以生成SQL:

declare @newID varchar(12) = '149080'
declare @oldID varchar(12) = '146423'

SELECT 'UPDATE ' + t.name + ' SET ' + c.name + ' = ' + @newID + ' WHERE ' + c.name + ' = ' + @oldID + ';'
FROM        sys.columns c
JOIN        sys.tables  t   ON c.object_id = t.object_id
WHERE       c.name = 'UserID'

是否可以执行这些语句?

1 个答案:

答案 0 :(得分:7)

正如我在评论中提到的那样,您需要使用动态SQL来实现这一点。一种方法如下:

DECLARE @newID int = 149080; --Changed datatype, I assume correct
DECLARE @oldID int = 146423; datatype, I assume correct

DECLARE @SQL nvarchar(MAX);

SET @SQL = STUFF((SELECT NCHAR(13) + NCHAR(10) + 
                         N'UPDATE ' + QUOTENAME(s.[name]) + N'.' + QUOTENAME(t.[name]) + N' SET ' + QUOTENAME(c.[name]) + N'= @NewID WHERE ' + QUOTENAME(c.[name]) + N' = @OldID;'
                  FROM sys.columns c
                       JOIN sys.tables t ON c.object_id = t.object_id
                       JOIN sys.schemas s ON t.schema_id = s.schema_id
                  WHERE c.[name] = N'UserID'
                  FOR XML PATH(''),TYPE).value('.','nvarchar(MAX)'),1,2,N'');

PRINT @SQL; --Your best friend for debugging
--SELECT @SQL; --If @SQL has a value more than 4,000 characters
EXEC sp_executesql @SQL, N'@NewID int, @OldID int', @NewID = @newID, @OldId = @oldID;

PRINTSELECT将帮助您调试。但是,就像我在评论中说的那样,您可能想在这里查看您的外键约束。