カーソルと動的 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 のデータ型をソース列と一致させることをお勧めします。変数は、データベース内の任意のデータ型にすることができます (ローカル一時型でない限り)。上記のコードには、型が定義されている場所が 2 つあります。1 つ目は変数が宣言されている場所で、2 つ目は sp_executesql の引数が下部近くの文字列で定義されている場所です。
注: @stmt と @params に変数ではなく定数が割り当てられている場合は、定数の前に N を付けて、Unicode 文字列として読み取られるようにしてください。