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子句的执行顺序的主要内容,如果未能解决你的问题,请参考以下文章