如何编写支持动态表名的存储过程查询col2为null的col1去重值并打印
存储过程修复实现
原代码问题说明
- 表名属于SQL语法对象,不能直接作为变量传入普通查询语句,必须使用动态SQL执行
- 缺少
col2 IS NULL的过滤逻辑,不符合需求中筛选col2为null记录的要求 - 未实现多值拼接逻辑,原有
col1=@result的赋值方式只会保留最后一条查询结果,无法得到逗号分隔的去重值列表 - 未对传入的表名参数做转义处理,存在SQL注入安全隐患
可运行实现代码
适配SQL Server 2017及以上版本(支持STRING_AGG函数)
CREATE PROC sp_getValue @tableName VARCHAR(30) AS BEGIN DECLARE @sql NVARCHAR(MAX), @result NVARCHAR(MAX) -- 用QUOTENAME转义表名,避免SQL注入风险 SET @sql = N' SELECT @result = STRING_AGG(DISTINCT col1, '','') FROM ' + QUOTENAME(@tableName) + N' WHERE col2 IS NULL ' -- 执行动态SQL,接收返回的拼接结果 EXEC sp_executesql @sql, N'@result NVARCHAR(MAX) OUTPUT', @result = @result OUTPUT PRINT @result END
兼容SQL Server 2016及以下低版本写法
CREATE PROC sp_getValue @tableName VARCHAR(30) AS BEGIN DECLARE @sql NVARCHAR(MAX), @result NVARCHAR(MAX) SET @result = '' SET @sql = N' SELECT @result = @result + col1 + '','' FROM ( SELECT DISTINCT col1 FROM ' + QUOTENAME(@tableName) + N' WHERE col2 IS NULL ) AS tmp ' EXEC sp_executesql @sql, N'@result NVARCHAR(MAX) OUTPUT', @result = @result OUTPUT -- 移除末尾多余的逗号 IF LEN(@result) > 0 SET @result = LEFT(@result, LEN(@result) - 1) PRINT @result END
测试方式
执行如下语句即可验证效果,替换为你实际的表名:EXEC sp_getValue '你的测试表名'
传入样例表执行后,输出结果为a,b,符合预期。
内容的提问来源于stack exchange,提问作者varen
相关产品推荐
相关产品推荐

