如何在存储过程中获取含值参数的名称列表?
解决存储过程中记录已传入参数名的问题
你有一个包含10个可选参数的存储过程usp_MySP,执行时仅传入@Weight和@Haircolor的值,需要将这两个被使用的参数名存入变量@MyParams,但原写法因NULL值拼接导致整体结果为NULL,以下是可行的解决方案:
方案1:使用CONCAT_WS函数(SQL Server 2017及以上版本)
CONCAT_WS会自动忽略NULL值,并用指定分隔符拼接非NULL内容,无需额外处理多余分隔符,是最简洁的方案:
DECLARE @MyParams varchar(100); -- 存储过程内已声明各参数的前提下 SET @MyParams = CONCAT_WS(', ', CASE WHEN @Name IS NOT NULL THEN 'Name' END, CASE WHEN @Height IS NOT NULL THEN 'Height' END, CASE WHEN @Weight IS NOT NULL THEN 'Weight' END, CASE WHEN @Haircolor IS NOT NULL THEN 'Haircolor' END, CASE WHEN @Eyecolor IS NOT NULL THEN 'Eyecolor' END -- 剩余6个参数按此格式依次添加 );
当仅传入@Weight和@Haircolor时,@MyParams会直接得到'Weight, Haircolor'。
方案2:使用STUFF+ISNULL拼接(兼容低版本SQL Server)
如果你的SQL Server版本低于2017,可采用这种方式:先拼接带前缀分隔符的内容,再移除开头的多余分隔符:
DECLARE @MyParams varchar(100); SET @MyParams = STUFF( ISNULL(', ' + CASE WHEN @Name IS NOT NULL THEN 'Name' END, '') + ISNULL(', ' + CASE WHEN @Height IS NOT NULL THEN 'Height' END, '') + ISNULL(', ' + CASE WHEN @Weight IS NOT NULL THEN 'Weight' END, '') + ISNULL(', ' + CASE WHEN @Haircolor IS NOT NULL THEN 'Haircolor' END, '') + ISNULL(', ' + CASE WHEN @Eyecolor IS NOT NULL THEN 'Eyecolor' END, '') -- 剩余6个参数按此格式依次添加 , 1, 2, '');
STUFF(..., 1, 2, '')会把字符串开头的, 替换为空,确保结果格式正确。
方案3:使用STRING_AGG聚合(SQL Server 2017及以上版本)
这种方式更易维护,尤其参数数量较多时,逻辑清晰直观:
DECLARE @MyParams varchar(100); SET @MyParams = ( SELECT STRING_AGG(param_name, ', ') FROM ( VALUES ('Name', @Name), ('Height', @Height), ('Weight', @Weight), ('Haircolor', @Haircolor), ('Eyecolor', @Eyecolor) -- 剩余6个参数按 (参数名, 参数变量) 格式添加 ) AS params(param_name, param_value) WHERE param_value IS NOT NULL );
通过构造临时结果集,过滤掉值为NULL的参数,再用STRING_AGG聚合为逗号分隔的字符串。
关于你原写法的问题
你原来的写法存在两处问题:一是逻辑错误,NULLIF(@name, 'name')是当@name等于字符串'name'时返回NULL,这和判断参数是否被传入无关;二是SQL中只要有一个NULL参与+拼接,整个结果就会变为NULL,因此这种写法既不符合需求,也存在技术缺陷,并非最优解。
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

