我会使用游标和动态 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 字符串读取。