存储过程中的SQL IN子句

时间:2012-07-06 00:16:50

标签: c# sql sql-server-2005 stored-procedures

我有一个传递以下数据的C#应用​​程序:

datasetID = 10; userID = 1; varnames =“'ACT97','ACTCHNG','ACTQTR2','ACTSCOR2'”;

存储过程是:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[s_LockCheck]
-- Add the parameters for the stored procedure here
@varNames VARCHAR(max),
@datasetID INT,
@userID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

SELECT COUNT(*) as locked FROM VarLocks WHERE var_name IN (@varNames) AND dataset_id = @datasetID AND user_id != @userID AND is_locked = 1

END

但是当我这样称呼它时,当它应该高于那个时它会返回0:

exec s_LockCheck "'ACT97','ACTCHNG','ACTQTR2','ACTSCOR2'", 88, 14

上面的每个ACTXXX都是列var_name。

中的varname

为什么不正确执行IN子句?

1 个答案:

答案 0 :(得分:1)

有几种方法可以实现这一目标:

  1. 动态SQL,如本文所述:http://asheej.blogspot.com/2012/04/how-to-use-ms-sql-in-clause-with.html

  2. 指定变量中的每个项目(如果你有很多人,这可能会非常难看):

    @ var1 varchar(20), @ var2 varchar(20), @ var3 varchar(20)

  3. 编写一个split函数将字符串转换为表变量,其中有很多。这是我个人的最爱:http://dataeducation.com/faster-more-scalable-sqlclr-string-splitting/

  4. 使用表值参数(2008):http://www.techrepublic.com/blog/datacenter/passing-table-valued-parameters-in-sql-server-2008/168

  5. 这是使用CHARINDEX的一个小技巧(注意这种方法是不可分的):

  6. 你的字符串是这样的:'abc,def'

    使用CHARINDEX,您可以使用分隔符填充搜索字符串和要在搜索字符串中找到的值。所以使用我的小例子,字符串将变为',abc,def,'注意开头和结尾的额外逗号。然后对字段数据执行相同的操作。如果您的数据中有逗号,则必须将分隔符换成其他内容,例如char(2)或分号,或其他任何内容。

    然后执行搜索:

    WHERE CHARINDEX ( ',' + expressionToFind + ',' , ',' + expressionToSearch ',') > 0
    

    分隔符填充使搜索无法找到“abcabc”,但会找到“abc”,完全匹配。

    如果您使用的是2005,我会抓住一个非常快速的分割功能,以避免使用动态SQL。