Я хочу добавить 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 таблиц это должно быть выполнимо, даже если немного медленнее.

1
SSingh 13 Сен 2018 в 19:10

2 ответа

Лучший ответ

В вашем цикле 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 
1
Ryan Wilson 13 Сен 2018 в 17:31

Вот как я бы это сделал.

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
0
Markov 13 Сен 2018 в 17:52