【问题标题】:Loop through a resultset循环遍历结果集
【发布时间】:2019-02-18 10:14:57
【问题描述】:

我想在我的数据库中的大约一百个表中添加 4 个新列。为此,我使用以下内容:

SET NOCOUNT ON
DECLARE @T NVARCHAR(100)
DECLARE @SQL NVARCHAR(MAX)

DECLARE TABLE_CURSOR CURSOR FOR 
SELECT DISTINCT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME LIKE '%ABC_%'

 OPEN TABLE_CURSOR

 FETCH NEXT FROM TABLE_CURSOR 
 INTO @T
    WHILE @@FETCH_STATUS = 0
        BEGIN

            SET @SQL = N'ALTER TABLE ' + Quotename(@T) +
                'ADD COL1 NVARCHAR(50),
                    COL2 NVARCHAR(50),
                    COL3 NVARCHAR(10),
                    COL4 NVARCHAR(6)'
            EXEC (@SQL)

        END 
CLOSE TABLE_CURSOR  
DEALLOCATE TABLE_CURSOR

我也尝试过使用+@T + 而不是 Quotename,但发生的情况是列被添加到结果集中的第一个表中,但随后由于内存不足异常错误而崩溃。

是否有更好/更有效的方法来遍历结果集并添加这些列?我可以建立一个 SSIS 来做到这一点,但不能保证它会起作用。我知道游标通常很慢,但我认为对于 100 个表,即使有点慢也应该可行。

【问题讨论】:

    标签: sql sql-server-2012 cursor dynamic-sql


    【解决方案1】:

    在您的WHILE 循环中,您缺少Fetch Next,没有它,它会创建一个无限循环,这就是您获得out of memory exception 的原因:

    WHILE @@FETCH_STATUS = 0
            BEGIN
    
                SET @SQL = N'ALTER TABLE ' + Quotename(@T) +
                    'ADD COL1 NVARCHAR(50),
                        COL2 NVARCHAR(50),
                        COL3 NVARCHAR(10),
                        COL4 NVARCHAR(6)'
                EXEC (@SQL)
    
                --Need this next line to move the cursor to the next record
                --Without this you create an infinite loop
                FETCH NEXT FROM TABLE_CURSOR INTO @T
    
    
            END 
    

    【讨论】:

    • 感谢 Ryan 像做梦一样工作,不到一秒就执行完毕。
    • @SSingh 很高兴我能帮上忙,给出的另一个答案是在不使用游标的情况下构建动态 sql 的好方法,因此您可能也想看看。编码愉快!
    【解决方案2】:

    这是我的做法。

    DECLARE @SQL varchar(max);
    SET @SQL = '';
    SELECT @SQL = @SQL + 'ALTER TABLE '+ CAST(QUOTENAME(s.name) as Varchar(10))+'.'+Cast(QUOTENAME(t.name) as VARCHAR(50)) + ' ADD COL1 NVARCHAR(50), COL2 NVARCHAR(50),COL3 NVARCHAR(10), COL4 NVARCHAR(6); '
    FROM sys.tables t
    Join sys.all_columns ac on t.object_id = ac.object_id --Remove this join if you arent searching for tables with specific name
    JOIN sys.schemas s on t.schema_id = t.schema_id
    Where t.type = 'U' --tables 
          and s.schema_id = 1 --Your shema ID 
        --and ac.Name like '%Tables with this column%'
    
    --Exec(@SQL)
    PRINT @SQL
    

    【讨论】:

      猜你喜欢
      • 2010-12-17
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 2019-11-30
      • 1970-01-01
      • 2018-08-09
      • 2015-10-05
      相关资源
      最近更新 更多