【问题标题】:Execution order of WHEN clauses in a CASE statementCASE语句中WHEN子句的执行顺序
【发布时间】:2014-08-23 03:04:43
【问题描述】:

鉴于以下案例陈述的主体:

1    WHEN r.code= '00'                        then 'A1'
2    WHEN r.code ='01' AND r.source = 'PXWeb' then 'A2'   <
3    WHEN r.code ='0120'                      then 'A3'
4    WHEN r.code ='01'                        then 'A4'   <
5    WHEN r.code ='1560'                      then 'A5'
6    WHEN r.code ='1530'                      then 'A6'
7    WHEN r.code ='1550'                      then 'A7'

我假设第 2 行总是在第 4 行之前执行?然后我读到像“SQL 是一种声明性语言,这意味着它告诉 SQL 引擎要做什么,而不是如何做”这样的语句

Order Of Execution of the SQL query

想知道这是否也与 CASE 语句中的执行顺序有关。本质上,我可以保留上面的代码,而不必将第 4 行更改为

4    WHEN r.code ='01' AND r.source != 'PXWeb' then 'A4'   

【问题讨论】:

    标签: sql case sybase case-when


    【解决方案1】:

    返回的值将是最早匹配的WHEN 子句(以文本形式)的THEN 表达式的值。这确实意味着,如果满足第 2 行条件,结果将是 A2

    但是,如果您的 THEN 表达式比文字值更复杂,那么即使不需要该表达式,也可能会进行一些评估这些表达式的工作。

    例如

     WHEN r.code= '00'                        then 'A1'
     WHEN r.code ='01' AND r.source = 'PXWeb' then 'A2'
     WHEN r.code ='0120'                      then 1/0
     WHEN r.code ='01'                        then 'A4'
    

    可以生成除以零错误,即使 r.code 不等于 0120,即使它等于 00,例如。我不知道标准对这个特定问题有什么规定,但我知道某些产品确实如此。

    【讨论】:

    • 我在 2008 年标准草案中进行了快速查找,奇怪的是它似乎根本没有说明案例顺序。但是,通常在计算机语言中,case 表达式中的 case 会按照指定的顺序进行测试。
    • @ErwinSmout - 我不敢相信我从来没有跟进你的评论。这里的区别在于 SQL 是一种 声明性 语言。不是程序。它是根据整体逻辑指定的,只要它仍然在逻辑上计算它所要求的结果,评估顺序就无关紧要。不幸的是,某些系统(这里值得注意的是 SQL Server)产生的错误应该在逻辑上排除影响最终结果。理想/现实之间的冲突。
    • “声明式”旨在针对数据的物理访问(在 RM 之前如此普遍的“指针追逐”)。显然,您无法逃避这样一个事实,即 case 表达式实际上只是编写嵌套 IF/THEN/ELSE 的一种隐藏方式,在某种意义上,它不可避免地比其他一些语言结构具有“更多的程序性”。我同意如果“评估顺序无关紧要”会更好,但不幸的是证明这对于任何编译器通常都不可行。不可避免,因此语言定义者必须承担后果。
    • @ErwinSmout - 好吧,它还旨在帮助揭露并行性。这就是为什么在 SQL 中的许多地方,计算顺序被认为是“好像所有表达式都在并行计算”。 IE。这就是为什么SELECT 子句表达式不能依赖于同一子句中的其他表达式的原因。
    【解决方案2】:

    AFAIK,CASE 评估的顺序将是您在查询中指定的顺序。所以在你的情况下,评估顺序将是1,2,3,4 ... , 7

    我可以保留上面的代码,而不必将第 4 行更改为

    您可以更改您的第二个CASE 并包括一个ELSE 部分,如下所示,它将负责第四个CASE 评估,您可以完全删除第四个评估

    2    WHEN r.code ='01' AND r.source = 'PXWeb' then 'A2' ELSE 'A4'  
    

    【讨论】:

    • 当 r.code = '02' 这不是问题的预期输出时,此解决方案将输出 'A4'
    【解决方案3】:

    没关系:

    “CASE 语句按顺序评估其条件,并在满足条件的第一个条件处停止。”

    http://msdn.microsoft.com/en-gb/library/ms181765.aspx

    【讨论】:

    • 但请注意下面的警告,这是我的回答所警告的:“在某些情况下,在 CASE 语句接收表达式的结果作为其输入之前评估表达式”
    猜你喜欢
    • 2023-01-21
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    • 2014-08-14
    • 1970-01-01
    相关资源
    最近更新 更多