sp_msforeachtable выполнение действий над переменными
Я пытаюсь выяснить, как использовать sp_msforeachtable для выполнения действий со всеми таблицами и переменными, которые соответствуют именам переменных / таблиц, хранящихся в другой таблице.
IE
У меня есть таблица, которая имеет 3 столбца: таблица, переменная, действие
и я пытаюсь использовать sp_MSforeachtable, чтобы увидеть, какие таблицы и переменные совпадают, и, если совпадают, выполнить это действие над таблицей.
Как вы называете имена переменных в операторе sp_MSforeachtable? Я знаю, чтобы использовать? для имени таблицы, но не знаю, как бы я сказал, если имя переменной = имя переменной, то сделайте X
Есть ли другой способ сделать это без использования этого недокументированного SP?
Я постараюсь объяснить лучше:
Я пытаюсь удалить личную информацию из нескольких таблиц... У меня есть таблица, которая выглядит следующим образом (не знаю, как форматировать таблицу, поэтому представьте, что каждая запись - это отдельная строка, поэтому первая строка - это Имя, A, и установите в '')
переменная
название
Номер телефона
название
Таблица
В
действие
Установлен в ''
Установите на "555-555-5555"
Установлен в ''
и т.п.
Затем у меня есть база данных, полная таблиц.... в таблице A я бы хотел, чтобы мой код устанавливал все строки переменной 'Name'
к '' (пусто)
и номер телефона для "555-555-5555"
и т.д., а затем перейти к таблице B и сделать то же самое и так далее
1 ответ
Я бы использовал курсор и динамический SQL:
--Set up for test:
CREATE TABLE #DataTable (column1 nvarchar(128) NOT NULL, column2 int NOT NULL); --Create global temp table so it can be accessed from dynamic SQL.
CREATE TABLE ##ActionTable ([table] nvarchar(128) NOT NULL, variable nvarchar(MAX) NOT NULL, [action] nvarchar(MAX) NOT NULL);
INSERT INTO ##ActionTable ([table], variable, [action])
VALUES
('#DataTable', '1', 'INSERT INTO @table (column1, column2) VALUES (''@variable_1'', @variable);'),
('#DataTable', '2', 'INSERT INTO @table (column1, column2) VALUES (''@variable_1'', @variable);'),
('#DataTable', '3', 'INSERT INTO @table (column1, column2) VALUES (''@variable_1'', @variable);'),
('#DataTable', '4', 'INSERT INTO @table (column1, column2) VALUES (''@variable_1'', @variable);');
--Code:
DECLARE @action nvarchar(MAX);
DECLARE @table nvarchar(128);
DECLARE @variable nvarchar(MAX);
DECLARE rowCurser CURSOR FOR SELECT [table], variable, [action] FROM ##ActionTable;
OPEN rowCurser;
FETCH rowCurser INTO @table, @variable, @action
WHILE @@FETCH_STATUS = 0
BEGIN
--Execute the code (pick one of the two. Option 2 is safer and can be cached (faster), but it does not work with my example because the parameters are left as variables).
-- Option 1:
SET @action = REPLACE(REPLACE(@action, '@table', @Table), '@variable', @variable);
EXECUTE(@action);
-- Option 2:
EXECUTE sp_executesql @stmt = N'INSERT INTO #DataTable (column1, column2) VALUES (CAST(@variable as nvarchar(128)) + N''_2'', @variable);', @params = N'@variable nvarchar(MAX)', @variable = @variable;
--Setup for next iteration
FETCH rowCurser INTO @table, @variable, @action
END
CLOSE rowCurser;
DEALLOCATE rowCurser;
--Check and cleanup from test
SELECT * FROM #DataTable;
DROP TABLE #DataTable;
DROP TABLE ##ActionTable;
Примечание. Проблемы, связанные с тем, что вы пытаетесь сделать, связаны с безопасностью, поскольку любой, кто может добавить вашу таблицу, будет иметь тот же доступ, что и учетная запись, которая запускает сценарий. Вы можете уменьшить эти проблемы, определив действия в другой таблице, которые могут редактировать только администраторы, а затем сослаться на действие в существующей таблице.
Примечание. Лучше всего, чтобы типы данных @action, @table и @variable соответствовали исходным столбцам. Переменные могут быть любыми типами данных в вашей базе данных (если это не локальный временный тип). Вы заметите, что в приведенном выше коде есть два места, где определены типы, во-первых, где переменные объявлены вверху, и во-вторых, где аргументы для sp_executesql определены в строке рядом с нижним.
Примечание: если @stmt и @params назначаются с константой, а не с переменной, убедитесь, что константа имеет префикс N, чтобы она читалась как строка Unicode.