在存储过程中动态创建IN子句

Man*_*hah 7 sql stored-procedures sql-server-2008

可能重复:
使用IN Clause在动态查询中需要帮助

我正在使用SQL Server 2008,这是我面临的问题.我有一个名为Cars的表,其中有一个专栏公司.现在我有一个看起来像这样的存储过程

CREATE PROCEDURE FindCars (@CompanyNames varchar(500))
AS
SELECT * FROM Cars WHERE Company IN (@CompanyNames)

我试过这样的事情但失败了

DECLARE @CompanyNames varchar(500)
SET @CompanyNames = '''Ford'',''BMW'''

exec FindCars @CompanyNames

我没有得到任何行返回.当我做以下

DECLARE @CompanyNames varchar(500)
SET @CompanyNames = '''Ford'',''BMW'''

Select @CompanyNames

我得到以下结果

'Ford','BMW'

如果我在存储过程内的select语句中替换此值,它可以工作

SELECT * FROM Cars where Company in ('Ford','BMW')

因此,我认为存储过程似乎被'Ford','BMW'视为一个字符串而不是数组.有人可以帮我这个.如何动态构造存储过程中select语句的IN子句中所需的字符串/数组.

Mat*_*lie 7

你是对的,你创建了一个字符串,并且它被处理为包含一个字符串的字符串列表.逗号只是该字符串中的字符.SQL Server中唯一的数组等效项是表.

例如; WHERE x IN (SELECT y FROM z).

出于这个原因,许多人创建了一个SPLIT_STRING()函数,该函数返回给定逗号分隔字符串的项目表...

WHERE x IN (SELECT item FROM dbo.split_string(@input_string))
Run Code Online (Sandbox Code Playgroud)

有很多方法可以实现拆分字符串.一些返回字符串,一些转换为整数,一些接受第二个"分隔符"参数,等等.您可以搜索互联网SQL SERVER SPLIT STRING并获得许多结果 - 包括在StackOverflow中.


另一种方法是使用动态SQL; 编写SQL的SQL.

SET @sql = 'SELECT * FROM x WHERE y IN (' + @input_string_list + ')'

SP_EXECEUTESQL @sql
Run Code Online (Sandbox Code Playgroud)

(我推荐SP_EXECUTESQL的只是EXEC因为前者允许你使用参数化查询,但后者不允许.)