【问题标题】:Using CASE expression inside a where clause在 where 子句中使用 CASE 表达式
【发布时间】:2019-10-24 14:59:12
【问题描述】:

我有一个带有 2 个参数的存储过程,都是整数

我需要在 where 子句中使用 case 语句,但我做错了

where 
dbo.StockTransfer.BranchId = @branchId 
AND
CASE WHEN IsNumeric(@roleId) = 1 
THEN 
dbo.StockTransfer.StatusId !=12    
ELSE
dbo.StockTransfer.StatusId NOT in (12, 13)  
  END

order by dbo.StockTransfer.StatusId ASC

我在“dbo.StockTransfer.StatusId !=12”中遇到错误

消息 102,级别 15,状态 1,过程 GetDeliveryList,第 44 行 [批处理开始第 0 行]
'!' 附近的语法不正确。

【问题讨论】:

  • 这是对case表达式的常见误解。它用于返回标量值。您正在尝试使用它来控制它无法执行的逻辑流。还要小心 IsNumeric。对于一些非常有趣但显然不是数字的值,它返回 true。 ;)
  • 嗨@sean Lange,感谢您提供的信息!我有 3 个 statusId(12,13 和 14),我想要实现的是如果 roleId = 1 我应该只返回那些 statusId 为 13 和 14 的记录,如果 roleId 不等于 1 我应该只返回那些记录statusId 14。有没有办法做到这一点?
  • This answer 适用于 join 条件和 where 子句。这是一个case 表达式,而不是语句。正如 Sean Lange 所说,IsNumeric() 是臭名昭著的 problematic
  • 所以你永远不想要 12 的状态?
  • @HABO - 哈哈,OP 似乎很难像 MS 一样将其称为表达式和语句。它们在问题标题中有表达,但在问题主体中有陈述。虽然最新的 MS 文档终于解决了那里的歧义。

标签: sql sql-server tsql case


【解决方案1】:

不要打扰。只需使用常规逻辑:

where dbo.StockTransfer.BranchId = @branchId and
      ( (IsNumeric(@roleId) = 1 and 
         dbo.StockTransfer.StatusId <> 12
        ) or
        (IsNumeric(@roleId) = 0 and
         dbo.StockTransfer.StatusId not in (12, 13)
        )
     ) 

这不处理 NULL 值,但可以轻松添加。

其实我可以简化为:

where dbo.StockTransfer.BranchId = @branchId and
      dbo.StockTransfer.StatusId <> 12 and
      (IsNumeric(@roleId) = 1 or
       dbo.StockTransfer.StatusId <> 13
      )

【讨论】:

  • 感谢您的帮助!实际上我有 3 个 statusId(12,13 和 14),我想要实现的是如果 roleId = 1 我应该只返回那些 statusId 为 13 和 14 的记录,如果 roleId 不等于 1 我应该只返回那些statusId 为 14 的记录
【解决方案2】:

鉴于最新的 cmets 关于您想要返回的内容,我认为它会是这样的。为清楚起见,我在括号中添加了很多空格。

where dbo.StockTransfer.BranchId = @branchId 
    AND 
    (
        ( 
            @roleId = 1
            AND
            StatusId in (13, 14)
        )
        OR
        (
            @roleId <> 1
            AND
            StatusId = 14
        )
    )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    相关资源
    最近更新 更多