通过动态 SQL 设置 SQL 变量

Setting SQL Variable via Dynamic SQL

我知道我想多了,但我已经反对这个问题太久了,所以我正在寻求帮助。

这是我正在尝试的声明 运行:SELECT @cntMax = MAX(id) FROM [Raw_Item-FieldReport] 但是,table 名称是一个变量 @reportTable

这行不通:

SET @sql = 'SELECT @cntMax = MAX(id) FROM @reportTable'
EXEC sp_executesql @sql

我什至尝试在 SET @sql 中使用实际的 table 名称,但这也不起作用。 我没想到会这么难,请告诉我我遗漏了什么easy/obvious。

这里有完整的代码供需要的人使用:

DECLARE
    @inTable nvarchar(255) = 'Raw_Item',
    @reportTable nvarchar(255),
    @fieldName nvarchar(255),
    @cnt int,
    @cntMax int,
    @sql nvarchar(max)

SET @reportTable = @inTable + '-FieldReport'

SET @cnt = 1
SELECT @cntMax = MAX(id) FROM [Raw_Item-FieldReport]
PRINT @cntMax
SET @cntMax = 0

SET @sql = 'SELECT @cntMax = MAX(id) FROM [Raw_Item-FieldReport]'
EXEC sp_executesql @sql
PRINT @cntMax

SQL 服务器 12.0.2008.8(在 Azure 上)

您需要使用输出参数,否则SQL服务器不知道如何将动态SQL中的@cntMax连接到@cntMax不是动态 SQL 中的 ,因为它们是不同的范围。为了保护自己免受 SQL 注入(一些提示 here and here),请始终检查您的对象是否存在,并使用 QUOTENAME() 而不是手动添加方括号(并且您应该始终使用 QUOTENAME() 当根据用户输入或变量构建对象名称时,即使它们没有破折号等不良字符):

DECLARE @sql         nvarchar(max),
        @inTable     nvarchar(255) = N'Raw_Item',
        @reportTable nvarchar(255);

SET @reportTable = N'dbo.' + QUOTENAME(@inTable + '-FieldReport');

IF OBJECT_ID(@reportTable) IS NOT NULL
BEGIN
  SET @sql = N'SELECT @cntMax = MAX(id) FROM ' + @reportTable + N';';

  EXEC sys.sp_executesql @sql,
           N'@cntMax int output', 
           @cntMax = @cntMax OUTPUT;

  PRINT @cntMax;
END
ELSE
BEGIN
  PRINT 'Nice try, h@xx0rs!';
END

Always use schema reference (dbo), always use statement terminators,请尽量避免使用破折号 (-) 等无效标识符字符命名。还有一个额外的提示:始终在 N'nvarchar string literals'.

上使用 N 前缀