CASE语句中WHEN子句的执行顺序

Posted

技术标签:

【中文标题】CASE语句中WHEN子句的执行顺序【英文标题】:Execution order of WHEN clauses in a CASE statement 【发布时间】: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'   

【问题讨论】:

【参考方案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 语句接收表达式的结果作为其输入之前评估表达式”

以上是关于CASE语句中WHEN子句的执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server判断语句(IF ELSE/CASE WHEN )

verilog语句执行顺序的疑问?

使用多 case 语句时分区顺序子句出错

mysql执行顺序

SQL语句执行顺序

switch-case 执行顺序