sql - 通过动态 SQL 设置 SQL 变量
问题描述
我知道我想太多了,但是我已经反对这个太久了,所以我正在寻求帮助。
这是我要运行的语句:SELECT @cntMax = MAX(id) FROM [Raw_Item-FieldReport]
但是,表名是一个变量@reportTable
这不起作用:
SET @sql = 'SELECT @cntMax = MAX(id) FROM @reportTable'
EXEC sp_executesql @sql
我什至尝试在其中包含实际的表名,SET @sql
但这也不起作用。我没想到会这么难,请告诉我我错过了一些简单/明显的东西。
对于那些想要它的人,这是完整的代码:
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 Server 12.0.2008.8(在 Azure 上)
解决方案
您需要使用输出参数,否则 SQL Server 不知道如何在动态 SQL 中连接@cntMax
到@cntMax
不在动态 SQL 中,因为它们是不同的范围。为了保护自己免受 SQL 注入(此处和此处的一些提示),请始终检查您的对象是否存在,并使用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
始终使用模式引用( dbo
),始终使用语句终止符,并且请尽量避免使用无效的标识符字符命名事物,例如破折号 ( -
)。还有一个提示:始终在 .N
上使用前缀N'nvarchar string literals'
。
推荐阅读
- c# - 多个 HTTP 请求触发 HTTP Client 超时
- c# - 如何禁用对 DataGrid 的特定(最后)列的重新排序?
- javascript - Firebase 身份验证 onAuthStateChanged 在函数体后响应
- javascript - 为什么我在 console.log 上将下拉值显示为“未定义”?
- python - 如何将 *args 与整数列表一起使用?
- r - 需要帮助使用“Imager”包进行灰度化:灰度错误(im):图像应具有三个颜色通道
- python - 如何删除每个组的多索引数据框中的第一行?
- html - 不小心保存了源html而不是原始html
- javascript - 不确定如何在 JavaScript 中使用反引号
- ios - 下载多个文件,操作队列在后台模式下不稳定