如何在 SQL 服务器中的 CASE WHEN 语句中包含异常?

How can I include exceptions in my CASE WHEN Statements in SQL Server?

我正在 SQL Server Management Studio (v18.10) 中进行一个项目,基本上我需要的是对我们的一些规则进行异常处理。我们有一些函数可以根据它是偶数还是奇数来进行一些其他计算,但是因为存在“异常”,我也需要能够处理这些异常。这些数字存储为文本,因为在少于 3 个字符的情况下,它们需要有前导 0。下面的代码片段几乎就是我现在所拥有的。

CASE
    WHEN
        (Num % 2 = 0 
        OR Num = '001' 
        AND NOT (Num = '124')) 
        THEN /*Do something*/

    WHEN 
        (Num % 2 = 1 
        OR Num = '002' 
        AND NOT (Num = '123'))
        THEN /*Do a different thing*/

    ELSE /*Do something else*/
END

到目前为止,我在“偶数”部分的例外情况有效,只是奇怪的例外情况似乎不起作用。 (即 Num = '001' 被视为偶数,但 Num = '124' 也仍被视为偶数。)它似乎仍在读取它,然后不进入下一个 WHEN 语句。我也尝试过使用其他一些变体但没有成功。

AND Number <> '124'
AND Number <> 124
AND NOT Number = 124

我不明白为什么这些不起作用!我需要把例外放在第一位吗? AND 异常是否需要在 OR 异常之前进行?我总共有大约 10 个异常需要处理,“奇数”部分中的所有异常都不起作用。

所以您真的应该看看 SQL 服务器的运算符优先级图表。 https://docs.microsoft.com/en-us/sql/t-sql/language-elements/operator-precedence-transact-sql?view=sql-server-ver15

AND 的排名高于 OR,因此首先评估 AND。对于相同等级的运算符,它们总是从左到右。

让我们看看现在的情况。

WHEN
    (Num % 2 = 0 
    OR Num = '001' 
    AND NOT (Num = '124')) 
    THEN /*Do something*/

这真的意味着

  (Num % 2 = 0 
    OR (Num = '001' 
    AND NOT (Num = '124'))) 
  

因此,如果 Num 为 124,则第一部分 Num%2 为真并让它被处理。

这里有你真正需要的

(Num % 2 = 0 
        OR Num = '001') 
        AND NOT (Num = '124') 

TLDR:明确放置括号以避免 SQL 解释不正确