#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
Решение
Решением (одним из многих) может быть:
- Создать курсор созданных SQL-выражений
- В цикле
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').. )
выражении.