2013-11-26 24 views
2

我有一个存储过程,需要传递逗号分隔变量。使用逗号分隔值的VARCHAR参数创建IN子查询

例如,如果在一定条件存在,我会通过的国家代码的列表如下所示:

AU,RA,PK 

的项数可以改变。

在存储过程中,我需要在IN子句中使用这些物品,如如下:

WHERE CountryCode IN (@ExcludeCountries) 

有没有办法做到这一点?如果需要的话,我可以按照国家代码进入类似N'AU', N'RA', N'PK'的地方。

谢谢。

+2

有一百万重复这个...简短的答案是传递一个表,如果你可以或使用其中一个解析函数。 – Hogan

回答

-1

有两种方法做到这一点:使用

  1. 的​​参数构建表变量表是后者加入到您的查询
  2. 建立这样

    ... + 'WHERE CountryCode IN' (' + @ExcludeCountries + ')' ... 
    
    动态SQL语句

    ,然后用sp_executesql来执行语句

+0

但是要避免它 - 对于这样一个简单的任务,不需要使用动态SQL。 –

+0

@Yosi完全不同意。我做了很多次,总是依赖于情况。您提供的解决方案在某些情况下可能会导致性能不佳,而使用动态SQL则可以解决此问题 - 这取决于您的情况。 – gotqn

+0

在大多数情况下,当使用Dynamic Sql时 - 您在参数保护,代码可读性,查询编译和执行计划缓存以及可能反弹其他方面都失败了。你可以避免所有这些(甚至更好),但它更复杂。当子查询中有数千个值时,我的解决方案可能会导致性能不佳,用户是否描述过这种情况?我不这么认为...... –

0

在实践中我已经看到了使用下面的函数这个问题解决了。此函数分割字符串并返回包含指定值的表。然后使用它像这样...

... COUNTRYCODE IN(SELECT * FROM dbo.SplitString(@ExcludeCountries, ''))

注意,在这个例子中,逗号(” ,')是分隔符。我多年来一直使用这种方法,而且我没有遇到任何性能问题。

CREATE FUNCTION [dbo].[SplitString] 
(
@SplitStr nvarchar(MAX), 
@SplitChar nvarchar(5) 
) 
RETURNS @RtnValue table 
(
Data nvarchar(MAX) 
) 
AS 
BEGIN 
Declare @Count int 
Set @Count = 1 

While (Charindex(@SplitChar,@SplitStr)>0) 
Begin 
Insert Into @RtnValue (Data) 

Select 
Data = ltrim(rtrim(Substring(@SplitStr,1,Charindex(@SplitChar,@SplitStr)-1))) 

Set @SplitStr = Substring(@SplitStr,Charindex(@SplitChar,@SplitStr)+1,len(@SplitStr)) 
Set @Count = @Count + 1 
End 

Insert Into @RtnValue (Data) 
Select Data = ltrim(rtrim(@SplitStr)) 

Return 
END 
+0

我的答案已经提出了这个解决方案,为什么重复它? –

+0

我没有注意到它,直到我写我的答案。我的答案仍然完整,无需弄清楚其他问题。 – fossilcoder

+0

顺便说一句,正如你所看到的,我在这里是新的,我不认为重复的解决方案足以得到一个投票,它仍然解决了问题,并提供了一个完整的解决方案。 – fossilcoder