Изменить таблицы в схеме - PullRequest
       17

Изменить таблицы в схеме

0 голосов
/ 08 октября 2019

Я пытаюсь установить значение по умолчанию для столбца (Inserted_time), но сначала мне нужно проверить, существует ли столбец в таблицах. Если столбец не существует, мне нужно добавить этот столбец и присвоить ему значение по умолчанию. Я работаю с Sql Server Management Studio. Пока что я написал этот код:

IF EXISTS ( select TABLE_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_CATALOG = 'DB_COPY' and COLUMN_NAME = 'Inserted_Time')
    begin
    ALTER TABLE table_name ADD CONSTRAINT [Inserted_Time_Def] SET DEFAULT (sysdatetimeoffset()) FOR [Inserted_Time]
    end

    else

    ALTER TABLE table_name ADD COLUMN [Inserted_Time] CONSTRAINT [Inserted_Time_Def] DEFAULT (sysdatetimeoffset()) WITH VALUES

Как только я получу таблицы, в которых есть столбец, мне нужно добавить это имя_таблицы в команду Alter. Но я не могу этого сделать. Может кто-нибудь сказать, пожалуйста, как использовать table_names, извлеченные из оператора select в операторе alter?

Ответы [ 2 ]

0 голосов
/ 08 октября 2019

Если предположить , что каждая таблица находится в отдельной схеме, то вы можете сделать что-то вроде этого:

DECLARE @SQL nvarchar(MAX);
SET @SQL = STUFF((SELECT NCHAR(13) + NCHAR(10) +
                         CASE WHEN EXISTS (SELECT 1
                                           FROM INFORMATION_SCHEMA.COLUMNS C
                                           WHERE T.TABLE_SCHEMA = C.TABLE_SCHEMA
                                             AND T.TABLE_NAME = C.TABLE_SCHEMA
                                             AND C.COLUMN_NAME = N'Inserted_Time') THEN N'ALTER TABLE ' + QUOTENAME(T.TABLE_SCHEMA) + N'.' + QUOTENAME(T.TABLE_NAME) + N' ADD CONSTRAINT [Inserted_Time_Def] DEFAULT (sysdatetimeoffset()) FOR [Inserted_Time];'
                                                                                   ELSE N'ALTER TABLE ' + QUOTENAME(T.TABLE_SCHEMA) + N'.' + QUOTENAME(T.TABLE_NAME) + N' ADD COLUMN [Inserted_Time] CONSTRAINT [Inserted_Time_Def] DEFAULT (sysdatetimeoffset());'
                        END
                  FROM INFORMATION_SCHEMA.TABLES T
                  WHERE T.TABLE_CATALOG = N'DB_COPY'
                  FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,2,N'');

PRINT @SQL; --Your best friend. If more than 4,000 characters, use SELECT

EXECUTE sp_executesql @SQL;

Скорее всего, это будет очень далеко от решения CURSOR, если выиметь большое количество схем.

0 голосов
/ 08 октября 2019

Во-первых, вы хотите поместить все имена таблиц во временную таблицу, чтобы вы могли проходить через нее.

После этого вы можете использовать курсор для выполнения команды для каждого имени таблицы.

В моем примере я напечатал только команду, которую хотел выполнить. Таким образом, вы можете быть уверены, что код сначала будет делать то, что вы хотите.

Пример:

select TABLE_NAME As TableName INTO #TablesList from INFORMATION_SCHEMA.COLUMNS where TABLE_CATALOG = 'DB_COPY' and COLUMN_NAME = 'Inserted_Time'

DECLARE @TablesCursor as CURSOR;
DECLARE @TableName as NVARCHAR(max);

DECLARE @CommandToExecute as NVARCHAR(max);

SET @TablesCursor = CURSOR FOR SELECT TableName FROM #TablesList;

OPEN @TablesCursor;
FETCH NEXT FROM @TablesCursor INTO @TableName;

WHILE @@FETCH_STATUS = 0
BEGIN

 SET @CommandToExecute = 'ALTER TABLE ' + @TableName + ' WHAT YOU WANNA DO '
 PRINT @CommandToExecute
 --EXEC(@CommandToExecute)

 FETCH NEXT FROM @TablesCursor INTO @TableName;

END

CLOSE @TablesCursor;
DEALLOCATE @TablesCursor;
...