0

我有一个 C# 应用程序,它传入以下数据:

数据集ID = 10;用户 ID = 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 子句?

4

1 回答 1

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. 编写一个拆分函数将字符串转换为表变量,其中有很多。这是我个人最喜欢的一个: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 的一个小技巧(注意这种方法是 Non-Sargable):

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

使用CHARINDEX,您可以使用分隔符填充搜索字符串和要在搜索字符串中查找的值。因此,使用我的小示例,字符串将变为 ',abc,def,' 请注意开头和结尾处的额外逗号。然后对字段数据做同样的事情。如果您的数据中有逗号,则必须将分隔符换成其他内容,例如 char(2) 或分号等。

然后执行搜索:

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

分隔符填充可防止搜索找到“abcabc”,但会找到“abc”,完全匹配。

如果您使用的是 2005,我会使用一个非常快速的拆分功能,这样您就可以避免使用动态 SQL。

于 2012-07-06T00:35:33.580 回答