SQL Server动态SQL设置变量及表名为变量的问题咨询
核心错误点
- 动态SQL不支持直接将表名、列名这类标识符作为参数传入,必须提前拼接进SQL字符串,建议搭配
QUOTENAME()函数处理,可自动转义表名中的特殊字符(比如你用到的横杠),同时规避SQL注入风险。 - 你没有为
sp_executesql配置内外变量的映射规则,动态SQL的内部变量和外部上下文的变量是完全隔离的,要获取动态SQL的计算结果,需要显式将目标变量声明为输出参数。
修正后完整可运行代码
DECLARE @inTable nvarchar(255) = 'Raw_Item', @reportTable nvarchar(255), @fieldName nvarchar(255), @cnt int, @cntMax int, @sql nvarchar(max), @paramDef nvarchar(max) -- 存储动态SQL的参数声明 SET @reportTable = @inTable + '-FieldReport' -- 版本1:硬编码表名,解决输出参数映射问题 SET @cntMax = 0 SET @sql = 'SELECT @cntMaxInternal = MAX(id) FROM [Raw_Item-FieldReport]' -- 声明动态SQL内部参数,指定为输出类型 SET @paramDef = N'@cntMaxInternal INT OUTPUT' -- 执行时将内部参数的输出值绑定到外部变量 EXEC sp_executesql @sql, @paramDef, @cntMaxInternal = @cntMax OUTPUT PRINT @cntMax -- 版本2:使用表名变量的最终实现 SET @cntMax = 0 -- QUOTENAME会自动给表名加方括号,转义特殊字符 SET @sql = 'SELECT @cntMaxInternal = MAX(id) FROM ' + QUOTENAME(@reportTable) SET @paramDef = N'@cntMaxInternal INT OUTPUT' EXEC sp_executesql @sql, @paramDef, @cntMaxInternal = @cntMax OUTPUT PRINT @cntMax
补充说明
你之前硬编码表名也运行失败,就是因为缺少输出参数映射,动态SQL内部的赋值操作仅在自身作用域内生效,外部的@cntMax不会被更新。
内容的提问来源于stack exchange,提问作者Dizzy49
相关产品推荐
相关产品推荐

