【问题标题】:Using CASE in WHERE Statement when parameter has multiple values当参数有多个值时,在 WHERE 语句中使用 CASE
【发布时间】:2016-01-15 15:52:13
【问题描述】:

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

在我的 TblActivity 中有两个字段 TblActivity.ActivityServActIdTblActivity.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

【问题讨论】:

  • 我可以猜到,但你应该解释一下你是如何在@ServiceActivity中存储多个参数的
  • 嗨 Juan,感谢您整理我的问题 :) @ServiceActivity 是一个整数,我勾选了“允许多个值”。这是你的意思吗?
  • 你说当@ServiceActivity 有一个值时工作正常。所以我们需要知道如何在一个 Integer 中存储多个值
  • 我只是使用SSRS中多值参数的标准设置,即勾选“允许多个值”。据我所知,这会将它变成一个逗号分隔的列表。
  • 好的,那么 Philp 已经给出了你需要的答案 :)

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


【解决方案1】:

如果您的 @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 WHEN (@YESNOActivity) = 'Yes' THEN (',' + TblActivity.ActivityServActId + ',')ELSE 0 END)
  • LIKE (CASE WHEN ATYESNOActivity = 'Yes' THEN (',' + ATServiceActivity + ',') ELSE 0 END)
  • 必须使用 AT 而不是 @ 才能将代码发布到那里。不知道为什么
  • 我附上了一个DEMO,如果你能理解的话请告诉我。
【解决方案2】:

在 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 在这个问题上似乎非常明确。虽然很久以前我赞成第三个回复(带有表值参数的那个),但任何高票的答案都可以解决问题。理想的答案取决于您正在处理的整体问题。 (我对SSRS不熟悉,无法给出更具体的建议。)

【讨论】:

  • 我认为这是问题所在,但在评论 OP 中说是一个整数。
  • 我不确定这意味着什么,但我认为“勾选'允许多个值'”是来自应用程序方面的东西......?
  • 谢谢,是的,我知道这就是问题所在。我一直在搜索“SQL 子句参数”,并努力寻找我能理解的解决方案(不是 SQL 专家,因为你可能会说)。你有什么特别推荐的吗?
  • 将其作为链接添加到我的回复中。
【解决方案3】:

因此,经过一番折腾,我为此制定了一个简单的解决方法,完全放弃了对 CASE 的使用 - 但我怀疑这不是一种非常有效的做事方式。

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

AND

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

【讨论】:

    猜你喜欢
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2020-01-18
    相关资源
    最近更新 更多