首页 > 解决方案 > 在 SQL Server 的架构中更新每个表中的列

问题描述

我想更新Last_Modified给定模式中每个表中的列。如果同一表 ( ) 中的另一列被更新,则该列将使用最新时间戳ENDTIME进行更新。

为此,我在 SQL Server 中有以下脚本:

DECLARE @TotalRows FLOAT
SET @TotalRows = (SELECT COUNT(*) FROM table1)

DECLARE @TotalLoopCount INT
SET @TotalLoopCount = CEILING(@TotalRows / 100000)

DECLARE @InitialLoopCount INT
SET @InitialLoopCount = 1

DECLARE @AffectedRows INT
SET @AffectedRows = 0

DECLARE @intialrows INT;
SET @intialrows = 1

DECLARE @lastrows INT
SET @lastrows = 100000;

WHILE @InitialLoopCount <= @TotalLoopCount
BEGIN
    WITH updateRows AS
    (
        SELECT 
            t1.*, 
            ROW_NUMBER() OVER (ORDER BY caster) AS seqnum 
        FROM
            table1 t1
    )
    UPDATE updateRows 
    SET last_modified = ENDTIME AT TIME ZONE 'Central Standard Time'
    WHERE last_modified IS NULL 
      AND updateRows.ENDTIME IS NOT NULL
      AND updateRows.seqnum BETWEEN @intialrows AND @lastrows; 

    SET @AffectedRows = @AffectedRows + @@ROWCOUNT
    SET @intialrows = @intialrows + 100000
    SET @lastrows = @lastrows + 100000

    -- COMMIT
    SET @Remaining = @TotalRows - @AffectedRows
    SET @InitialLoopCount = @InitialLoopCount + 1
END

此脚本确定表的计数,将其除以 100000,然后只运行那么多循环来执行整个更新。它分批/循环分解更新,然后对某些行执行更新,直到完成全部更新。

此脚本仅适用于 1 个表,即 table1。我现在想修改这个脚本,使其动态地获取模式中的所有表并为每个表运行上述脚本。假设模式名称是 schema1,它有 32 个表,所以这个脚本应该为所有这 32 个表运行。

我能够检索 schema1 中的表,但无法将它们动态发送到此脚本。谁能帮我解决这个问题?

标签: sqlsql-serverssms

解决方案


要在运行时动态更改表名,您将需要 sp_executesql 之类的东西。有关其使用示例,请参见此处:https ://stackoverflow.com/a/3556554/22194

然后你可以有一个外部游标来获取表名,然后将查询组合成一个字符串并执行它们。它会看起来很可怕。

如果您的架构没有太大变化,另一种方法是生成一个长脚本,其中每个表都有一个部分。您可以通过查询表名然后使用每个不同的表名重复该脚本来生成脚本。Excel 实际上非常适合做这类事情 - 将表名粘贴到 Excel 中,使用 Excel 生成脚本,然后将其复制/粘贴回 SSMS。

这将是一个冗长的重复脚本,但可以避免将所有 SQL 都放在字符串中的缺点。


推荐阅读