将字符串参数格式化为IN语句

时间:2016-10-03 17:52:38

标签: sql-server tsql parameters

我有一些代码:

declare @GroupNames nvarchar(1024)
EXEC Utility.dbo.Get_ADGroups_ForUser 'rwm132' ,@GroupNames output
print @GroupNames

print语句如下所示:

'vQAHR','vQAResearch','vQAICT','vQAAdvancement','vAllResearch','vAllStudent','vQATeachLearn','vQAFinance','vQAHR'

(0 row(s) affected)

我有一个谓词

WHERE
     (
RLP.ALL_GROUP_NAME IN  ( @GroupNames )  
 ) 

这似乎不起作用我应该如何格式化字符串'以便它 作品。如果我复制该字符串并将其粘贴到谓词中的@GroupNames,那么它的工作文件只是替换中的某些内容似乎搞砸了。

2 个答案:

答案 0 :(得分:2)

您需要一个分割字符串函数

在Sql Server 2016中,您可以使用STRING_SPLIT函数

WHERE
(
RLP.ALL_GROUP_NAME IN  ( select value from STRING_SPLIT(@GroupNames,','))  
 ) 

对于以前的版本,请使用以下链接

中的任何一种方法

Split strings the right way – or the next best way

如果您为字符串中的每个值附加单引号,请使用此

WHERE
(
RLP.ALL_GROUP_NAME IN  ( select stuff(stuff(value,1,1,''),len(value)-1,1,'') from STRING_SPLIT(@GroupNames,','))  
 ) 

或者您可以使用Dynamic Sql,考虑到不会有任何 Sql注入,因为它是一个过程输出

declare @sql varchar(max)=''
set @sql ='
select ..
WHERE
RLP.ALL_GROUP_NAME IN  ( '+@str+') '

exec (@sql)

答案 1 :(得分:0)

如果不是2016年,您可以使用TVF分割或解析字符串

-- Notice the single quotes surrounding each item are not necessary 
Declare @GroupNames varchar(max) = 'vQAHR,vQAResearch,vQAICT,vQAAdvancement,vAllResearch,vAllStudent,vQATeachLearn,vQAFinance,vQAHR'

Select A.* 
 From  YourTable A
 Where RLP.ALL_GROUP_NAME in (Select RetVal from [dbo].[udf-Str-Parse](@GroupNames,','))

UDF(如果需要)

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From (Select x = Cast('<x>'+ Replace(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')

现在,只是为了好玩,如果你不想要UDF,你可以

Select A.*
 From  YourTable A
 Where RLP.ALL_GROUP_NAME In (Select Item=LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
                                From (Select x = Cast('<x>'+ Replace(@GroupNames,',','</x><x>')+'</x>' as xml).query('.')) as A 
                                Cross Apply x.nodes('x') AS B(i)
                             )