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

Using CASE in WHERE Statement when parameter has multiple values

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

在我的 TblActivity 中有两个字段 TblActivity.ActivityServActIdTblActivity.ActivityContractId 我想将它们包含在我的WHERE 语句。

按这些过滤是可选的。如果用户为参数 @YESNOActivity 选择 'Yes',那么我想过滤查询以查找 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

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

IN (1, 2, 3, 4)

你有

IN (@Param)

像这样的地方 @Param = '1, 2, 3, 4'

在内部,SQL 会把它变成

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

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

有多种方法可以解决这个问题。在 SO 中搜索 "sql in clause parameter",选择一个适合您的,然后点赞。


(已添加)

Parameterize an SQL IN clause 在这个问题上似乎很明确。很久以前,我对第三个回复(带有 table-value 参数的那个)投了赞成票,任何 high-vote 的答案都可以解决问题。理想的答案取决于您正在处理的总体问题。 (本人对SSRS不熟悉,无法给出更具体的建议。)

如果您的 @ServiceActivity 类似于 1,2,3

你可以这样做

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

所以你格式化你的变量

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

SQL FIDDLE DEMO

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,%'

为您服务

(CASE WHEN @YESNOActivity = 'Yes' 
           THEN ',' + @ServiceActivity + ','
           ELSE NULL 
 END)
LIKE
(CASE WHEN @YESNOActivity = 'Yes' 
           THEN '%,' + TblActivity.ActivityServActId + ',%'
           ELSE 0 
 END) 

因此,经过一番折腾之后,我通过完全放弃使用 CASE 来解决这个问题 - 但我怀疑这不是一种非常有效的做事方式。

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

AND

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