我有一个传递以下数据的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子句?
答案 0 :(得分:1)
有几种方法可以实现这一目标:
动态SQL,如本文所述:http://asheej.blogspot.com/2012/04/how-to-use-ms-sql-in-clause-with.html
指定变量中的每个项目(如果你有很多人,这可能会非常难看):
@ var1 varchar(20), @ var2 varchar(20), @ var3 varchar(20)
编写一个split函数将字符串转换为表变量,其中有很多。这是我个人的最爱:http://dataeducation.com/faster-more-scalable-sqlclr-string-splitting/
使用表值参数(2008):http://www.techrepublic.com/blog/datacenter/passing-table-valued-parameters-in-sql-server-2008/168
这是使用CHARINDEX的一个小技巧(注意这种方法是不可分的):
你的字符串是这样的:'abc,def'
使用CHARINDEX
,您可以使用分隔符填充搜索字符串和要在搜索字符串中找到的值。所以使用我的小例子,字符串将变为',abc,def,'注意开头和结尾的额外逗号。然后对字段数据执行相同的操作。如果您的数据中有逗号,则必须将分隔符换成其他内容,例如char(2)或分号,或其他任何内容。
然后执行搜索:
WHERE CHARINDEX ( ',' + expressionToFind + ',' , ',' + expressionToSearch ',') > 0
分隔符填充使搜索无法找到“abcabc”,但会找到“abc”,完全匹配。
如果您使用的是2005,我会抓住一个非常快速的分割功能,以避免使用动态SQL。