首页 > 解决方案 > 使用连接变量执行动态 SQL

问题描述

我有多个名称,如“abc”、“abc1”、“abc2”、“abc3”。我的目标是将值推送到下一列,因此:

abc3 = abc2
abc2 = abc1
abc1 = abc
abc = null

我写了这个:

DECLARE @name varchar(20)
SET @name = 'abc'

DECLARE @exec nvarchar(max)
SET @exec = 
    'UPDATE ' + @tbl + '
        SET ' + @name + '3 = ' + @name + '2,
        ' + @name + '2 = ' + @name + '1,
        ' + @name + '1 = ' + @name + ',
        ' + @name + '= ''''

EXEC sp_executesql @exec

但是,如果我想在其他地方更改名称“abc”并再次执行查询,则名称不会更新。

我找到了一种在 sp_executesql 命令中分配值的方法,但是我无法通过这种方式将名称值与数字连接起来。

是否可以创建这样的查询,我可以用不同的名称多次执行它?

我的想法是像那样运行它并在那里更改名称。

EXEC sp_executesql @exec, N'@name nvarchar(20)', @name = N'abc'
EXEC sp_executesql @exec, N'@name nvarchar(20)', @name = N'xyz'

标签: sqlsql-serverdynamic-sql

解决方案


老实说,这是一个非常奇怪的要求。看起来真正的问题是您的设计,因为它是非规范化的(应该只有 1name列,而不是 4 列)。

无论如何,您可以使用动态 SQL 来实现这一点。请注意,您需要确保正确引用动态对象非动态的参数值(例如您的 missing WHERE)。这可以处理安全注射,但它很丑陋......

DECLARE @schema sysname, --The data type used for object names. Synonym for nvarchar(128) NOT NULL
        @table sysname,
        @name sysname; 
--Assign @schema and @table too
SET @Name = N'abc';

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

SET @SQL = N'UPDATE ' + QUOTENAME(@schema) + N'.' + QUOTENAME(@table) + @CRLF +
           N'SET ' + QUOTENAME(@name) + N' = '''',' + @CRLF +
           N'    ' + QUOTENAME(@name + '1') + N' = ' + QUOTENAME(@name) + N',' + @CRLF +
           N'    ' + QUOTENAME(@name + '2') + N' = ' + QUOTENAME(@name + '1') + N',' + @CRLF +
           N'    ' + QUOTENAME(@name + '3') + N' = ' + QUOTENAME(@name + '2') + N';';
           --No WHERE?

--PRINT @SQL --Your Best Friend
EXEC sys.sp_executesql @SQL;

推荐阅读