Обновить несколько таблиц из результата запроса

#sql-server

#sql-server

Вопрос:

Возможно ли обновить несколько таблиц из результата запроса?

Я пробовал использовать курсор. Но это все еще не работает.

Вот код :

 DECLARE @TableName VARCHAR(MAX)

DECLARE db_cursor CURSOR FOR 
     SELECT TABLE_NAME  
     FROM information_schema.columns 
     WHERE column_name = 'Code1';

OPEN db_cursor  

FETCH NEXT FROM db_cursor INTO @TableName

WHILE @@FETCH_STATUS = 0
BEGIN 
    UPDATE @TableName 
    SET Code1 = Code   '_'   Type

    FETCH NEXT FROM db_cursor INTO @TableName
END

CLOSE db_cursor
DEALLOCATE db_cursor
  

Комментарии:

1. Не могли бы вы предоставить некоторые примеры данных и ожидать результата? это действительно помогает

2. Оператор DML может воздействовать только на одну таблицу одновременно; если это то, что вы спрашиваете. Вы можете использовать такие вещи, как вместо триггеров, чтобы создать «иллюзию» обновления нескольких таблиц (например, когда вы выполняете UPDATE над VIEW a), однако в триггере фактически будет обновляться только одна таблица за раз в соответствии с инструкцией DML в этом триггере. Вы не можете иметь такие вещи, как UPDATE Table1, Table2 SET IsActive = 0 WHERE ID = 1; и ожидать, что строки в обоих Table1 и Table2 будут обновлены.

3. В вашем примере показано обновление одной таблицы. Приведите пример того, как требуется обновить несколько таблиц одновременно.

4. @Greg Чего пытается достичь OP, так это создать динамический SQL для ОБНОВЛЕНИЯ всех таблиц в базе данных

Ответ №1:

Гипотеза

Я полагаю, что OP пытается динамически создавать и выполнять SQL-код для всех таблиц, имеющих столбец Code1

Решение

Решением (одним из многих) может быть:

  1. Создать курсор созданных SQL-выражений
  2. В цикле exec созданы выражения

Пример кода

 DECLARE @sql_code varchar(max)

DECLARE code_cursor CURSOR FOR
SELECT DISTINCT 
       'UPDATE '  TABLE_NAME   ' SET Code1= Code   ''_''   Type;' AS SQL_CODE
     FROM 
         information_schema.columns -- WHERE column_name = 'Code1';

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @sql_code

WHILE @@FETCH_STATUS = 0
BEGIN 
    exec(@sql_code)

    FETCH NEXT FROM db_cursor INTO @TableName
END
CLOSE db_cursor
DEALLOCATE db_cursor
  

Внимание

Я не тестировал это (по причине — у меня нет подобной базы данных) — так что будьте осторожны.

Обновить

Еще проще было бы изменить операционный код следующим образом:

 DECLARE @TableName VARCHAR(MAX)

DECLARE db_cursor CURSOR 
FOR SELECT DISTINCT TABLE_NAME   -- note DISTINCT here
    FROM information_schema.columns WHERE column_name = 'Code1'; 

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @TableName

WHILE @@FETCH_STATUS = 0
BEGIN 
EXEC('UPDATE '  @TableName   ' SET Code1 = Code   ''_''   Type') -- note EXEC here

FETCH NEXT FROM db_cursor INTO @TableName
END
CLOSE db_cursor
DEALLOCATE db_cursor
  

Комментарии:

1.Если у вас есть STRING_AGG — вы можете сделать еще проще: встроить в один оператор SQL все UPDATE -ы и EXEC это. Все можно было бы сделать в одном EXEC(SELECT STRING_AGG('UPDATE ' TABLE_NAME ' SET Code1= Code ''_'' Type;', 'n').. ) выражении.