TSQL SET 命令在 EXEC 语句中不起作用

TSQL SET command not working inside EXEC statement

我正在尝试 运行 SQL Server Management Studio 中的以下脚本:

DECLARE @counter INT = 1

EXEC('SET '+@counter+' = '+@counter+' + 1')

但是,我得到这个错误:

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '1'-

我已经排除故障好几天了,但一无所获 - 我猜 TSQL 很可能根本不接受 EXEC 命令中的这个,但我可以用什么来代替它?

这是一个更大的脚本的一部分,上面的内容必须在 EXEC 语句中才能使其余部分正常工作..

由于多种原因,这不会起作用。

让我们从你拥有的开始:

DECLARE @counter INT = 1

EXEC('SET '+@counter+' = '+@counter+' + 1')

EXEC 期望括号内有一个字符串,但您有一个 int(变量 @counter),所以这是您的第一个问题。但是,奇怪的是,您在这里没有遇到转换错误;似乎 @counter 被解释为其值 (1),而不是首先应用 Data Type Precedence。 (如果您尝试 SELECT 'SET '+@counter+' = '+@counter+' + 1',您将收到错误 “将 varchar 值 'SET ' 转换为数据类型 int 时转换失败。”)。

即使 如果 查询成功越过了这个障碍,那也会导致另一个错误,因为查询变为:

SET 1 = 1 + 1

显然这行不通,11,没有其他数字。

其次,在“动态”语句范围之外声明的变量不能在其中引用。让我们采取以下措施:

DECLARE @Varible int = 1;

EXEC (N'SELECT @Variable;');

这个returns错误:

Must declare the scalar variable "@Variable".

如果您使用的是“动态”语句(您的语句根本不是动态的),那么您需要对变量进行参数化。这就是为什么你不应该使用 EXEC ({SQL Statement}) 而应该使用 sys.sp_executesql.

因此,对于上述内容,您得到:

DECLARE @counter INT = 1;
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SET @Variable = @Variable + 1;';
EXEC sys.sp_executesql @SQL, N'@Variable int OUTPUT',@Variable = @counter OUTPUT;

SELECT @Counter;

正如我所提到的,这毫无意义,因为上面没有任何动态内容,您的查询应该只是:

DECLARE @counter INT = 1;
SET @counter = @counter + 1;

当然,none 甚至会继续解决诸如如何 安全地 将对象注入动态语句之类的问题,但那不是'这个问题是关于什么的。正如我所提到的,这里的动态语句是多余的,因为它不是动态的,并且不需要延迟解析(例如当您 ALTER a table 添加一列,然后尝试在同一批次中引用该列)。

如果你运行下面的脚本,它会抛出类似

的错误

Msg 137, Level 15, State 1, Line 1
Must declare the scalar variable "@counter".

BEGIN
    DECLARE @counter INT = 1
    EXEC('SET @counter = '+ @counter+' + 1')
END

为什么?

因为dynamic SQL不同范围到外部

所以可以试试这个方法(使用输出)

DECLARE @counter INT = 1
DECLARE @SQL nvarchar(50) = 'SELECT @counter2 =' + CAST(@counter + 1 AS VARCHAR(100))
exec sp_executesql @SQL, N'@counter2 int out', @counter out
SELECT @counter