SQL标准中错误值的处理

问题描述:

我有一个关于SQL标准的问题,我希望SQL language lawyer可以提供帮助。SQL标准中错误值的处理

某些表达式不起作用。例如,62/0。 SQL标准指定了几种表达式可能以类似方式出错的方式。许多语言使用特殊的特殊流量控制或bottom伪值处理这些表达式。

我有一个表,t,(仅)两列,xy每个类型int。我怀疑它是不相关的,但为了明确起见,我们假设(x,y)t的主键。此表包含(只)以下值:

x y 
7 2 
3 0 
4 1 
26 5 
31 0 
9 3 

由SQL标准需要在这个表上可以由零涉及部门(一个或多个)操作SELECT表达式是什么行为?或者,如果不需要任何行为,允许哪些行为?

例如,以下select语句需要什么行为?

最简单的一个:

SELECT x, y, x/y AS quot 
FROM t 

较硬的一个:

SELECT x, y, x/y AS quot 
FROM t 
WHERE y != 0 

,一个更难的一个:

SELECT x, y, x/y AS quot 
FROM t 
WHERE x % 2 = 0 

但愿没有认识到在实现(比方说,一个这个查询的一个更复杂的版本,限制可以在扩展中移动)被允许生产e响应于该查询而被零错误除法,因为在执行限制之前试图将3除以0作为扩展的一部分并且意识到3 % 2 = 1?例如,如果扩展是在一个小表上进行的,但结果 - 当与大表结合并根据大表中的数据进行限制时,结果会限制掉所有的行已经要求除以零。

如果t有数百万行,并且最后一个查询是通过表扫描执行的,那么在允许实现返回前几百万个结果,然后在遇到一个偶数值x y值为零?是否需要缓冲?

还有更糟糕的情况下,思考这一个,这取决于语义可以毁掉布尔短路或需要四个值的布尔逻辑在限制:

SELECT x, y 
FROM t 
WHERE ((x/y) >= 2) AND ((x % 2) = 0) 

如果表很大,这短暂的电路问题会变得非常疯狂。想象一下这个表有一百万行,其中一个有0的除数。会是什么标准说是语义:

SELECT CASE 
     WHEN EXISTS 
      (
       SELECT x, y, x/y AS quot 
       FROM t 
      ) 
     THEN 1 
     ELSE 0 
     END AS what_is_my_value 

好像这个值,因为它依赖于空虚或结果的非空虚这是一个错误,但是可能是一个错误采取这些语义会似乎禁止优化器在这里短路表扫描。此存在查询是否需要证明存在一个非底部行,或者是否存在底部行?

我很感谢这里的指导,因为我似乎无法找到规范的相关部分。

+1

你的问题对我没有意义;实现通常不是由标准规定的...... – 2009-07-17 01:03:20

我一直在使用的SQL的所有实现都将0作为立即的NaN#INF。该部门应该由前端处理,而不是由执行本身处理。查询不应该触底,但在这种情况下,结果集需要返回NaN。因此,它与结果集同时返回,并且不会向用户提供任何特殊警告或消息。

在任何情况下,要妥善处理这,使用以下查询:

select 
    x, y, 
    case y 
     when 0 then null 
     else x/y 
    end as quot 
from 
    t 

要回答你的最后一个问题,这样的说法:

SELECT x, y, x/y AS quot 
FROM t 

将返回此:

x y quot 
7 2 3.5 
3 0 NaN 
4 1  4 
26 5 5.2 
31 0 NaN 
9 3  3 

所以,你的exists会找到t的所有行,reg无论他们的商数是多少。

此外,我再次阅读你的问题,并意识到我没有讨论where条款(为羞愧!)。 where子句或predicate,应该在计算列之前应用总是

想想这个查询:

select x, y, x/y as quot from t where x%2 = 0 

如果我们有一个记录(3,0),它适用的where条件,如果3 % 2 = 0检查。它没有,所以它不包括在列计算中的记录,并将它保留在原来的位置。