通过动态 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
前缀
我知道我想多了,但我已经反对这个问题太久了,所以我正在寻求帮助。
这是我正在尝试的声明 运行: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
前缀