当参数有多个值时,在WHERE语句中使用CASE

时间:2016-01-15 15:52:13

标签: sql-server-2008 ssrs-2008-r2

我有一个问题,我认为与多值参数有关。

在我的TblActivity中,有两个字段 TblActivity.ActivityServActId TblActivity.ActivityContractId ,我希望将其包含在我的WHERE语句中。

通过这些过滤是可选的。如果用户选择“是”'对于参数@YESNOActivity,我想过滤查询,查找TblActivity.ActivityServActId与参数@ServiceActivity中的一个选项匹配的行。

@YESNOContractTblActivity.ActivityContractId@Contract分别适用

我设法达到了这个目标:

WHERE
(CASE WHEN @YESNOActivity = 'Yes' THEN TblActivity.ActivityServActId ELSE 0 END) 
IN (CASE WHEN @YESNOActivity = 'Yes' THEN @ServiceActivity ELSE 0 END)  

AND (CASE WHEN @YESNOContract = 'Yes' THEN TblActivity.ActivityContractId ELSE 0 END) 
IN (CASE WHEN @YESNOContract = 'Yes' THEN @Contract ELSE 0 END)

但是,如果在参数@ServiceActivity@Contract中只选择了一个值,此代码可以正常工作,只要我在这些参数中有多个值,就会出现错误:

Incorrect syntax near ','.
Query execution failed for dataset 'Activity'. (rsErrorExecutingCommand)
An error has occurred during report processing. (rsProcessingAborted)

谁能看到我做错了什么?我可以理解,如果我在WHERE语句中有一个=而不是IN但是无法解决这个问题。

使用SQL Server 2008和SSRS 2008-r2

3 个答案:

答案 0 :(得分:2)

在SQL中,IN子句不支持使用它们的方式。一般语法是

IN (1, 2, 3, 4)

你有

IN (@Param)
类似的东西    @Param ='1,2,3,4'

在SQL内部,SQL会将其转换为

IN ('1, 2, 3, 4')

注意引号......你现在正在匹配一个字符串!

有很多方法可以解决这个问题。在SO中搜索“sql in clause parameter”,选择一个适合你的方法,然后进行upvote。

(添加)

Parameterize an SQL IN clause似乎在这个问题上非常确定。很久以前我对第三个回复(带有表值参数的回复)进行了投票,任何高投票的答案都可以解决问题。理想的答案取决于您正在使用的整体问题。 (我不熟悉SSRS,也不能给出更具体的建议。)

答案 1 :(得分:2)

如果您的<p>类似于@ServiceActivity

你可以做这样的事情

1,2,3

所以你设置变量格式

WHERE  `,1,2,3,` LIKE `%,1,%` 

<强> SQL FIDDLE DEMO

WHERE  ',' + @ServiceActivity + ',' LIKE '%,' + ID + ',%'

为你的案件

SELECT *
FROM 
    (SELECT '1,2,3,4' as X UNION ALL
     SELECT '2,3,4,5' as X UNION ALL
     SELECT '3,4,5,6' as X UNION ALL
     SELECT '1,3,4,5' as X 
     ) as T
WHERE ',' + X + ','  LIKE  '%,1,%'

答案 2 :(得分:0)

因此,在经历了很多混乱之后,我通过完全放弃使用CASE来为此设置一个简单的解决方法 - 但我怀疑这不是一种非常有效的做事方式。

WHERE
(@YESNOActivity = 'No' OR (@YESNOActivity = 'Yes' AND
TblActivity.ActivityServActId IN (@ServiceActivity)))

AND

(@YESNOContract = 'No' OR (@YESNOContract = 'Yes' AND
TblActivity.ActivityContractId IN (@Contract)))