2011-04-20 57 views
2

我有一个具有nvarchar(max)参数@p1的SP。这是逗号分隔的代码列表,例如100,200,300SQL Server 2005 Single引用的字符串列表失败

的SP里面我声明一个变量@p2 nvarchar(max)@p1列表转换成一个单一的引用列表

set @p2 = N'''' + replace(@p1,',',''',''') + '''' 

当我“中选择” @p2这个返回正确的'100', '200', '300'

如果我再使用@p2,例如

select x,y,z from table1 where id in (@p2) 

我没有返回行吗?如果我修改相同的SQL来使用我从前面选择的相同的字符串,我得到的行确定吗?

如何将包含单引号标识符列表的字符串传递给SP并在子查询中使用它?我已经广泛使用Google,可以将列表转换为SP中的临时表并使用它,但我需要使用带引号的列表,以便使用OPTIMIZE FOR查询提示。

+0

感谢Quassnoi! – 2011-04-20 09:21:53

回答

2

IN不按照您期望的方式使用逗号分隔字符串:它被认为是单个字符串,而不是隐式数组值。

id IN ('101,102,103')只有在id为确切字符串'101,102,103'时才会匹配,而不是其任何单独分离的块。

你应该实现一个TVF which splits the string并返回一组成员,并使用它像:

SELECT * 
FROM table1 
WHERE id IN 
     (
     SELECT value 
     FROM tvf_split_string('101,102,103') 
     ) 
+0

太好了。对。我明白你来自哪里。我会去一个这个并回来。非常感激。 – 2011-04-20 09:30:58

0

一种选择是使用执行

Execute('select x,y,z from #1 where id in (' + @p2 + ')') 
1

由于Quassnoi说,你应该使用一个函数来分割字符串。这里有一个,我使用:

CREATE FUNCTION dbo.tvf_split_string 
(
    @List nvarchar(2000), 
    @SplitOn nvarchar(5) 
) 
RETURNS @RtnValue table 
(
    Id int identity(1,1), 
    Value nvarchar(100) 
) 
AS 
BEGIN 
    while (Charindex(@SplitOn,@List)>0) 
    begin 
     insert into @RtnValue (value) 
     select 
      Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1))) 

     set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List)) 
    end 
    insert Into @RtnValue (Value) 
    select Value = ltrim(rtrim(@List)) 

    return 
END 

,并调用它,如下所示:

SELECT值从 dbo.tvf_split_string( '101,102,103')