sql - SQL标准中错误值的处理

标签 sql error-handling language-design semantics

我有一个关于 SQL 标准的问题,我希望得到一个 SQL language lawyer可以帮忙。

某些表达方式是行不通的。 62 / 0 , 例如。 SQL 标准规定了许多表达式可能以类似方式出错的方式。许多语言使用特殊的异常流控制或 bottom 来处理这些表达式。伪值。

我有一张 table ,t ,(仅)两列,xy每个类型 int .我怀疑这无关紧要,但为了明确起见,我们假设 (x,y)t 的主键.此表包含(仅)以下值:

x    y
7    2
3    0
4    1
26   5
31   0
9    3
SELECT 的 SQL 标准要求什么行为?在此表上操作的表达式可能涉及除以零?或者,如果不需要任何一种行为,那么允许哪些行为?

例如,以下 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

是否允许实现(例如,在此查询的更复杂版本上未能意识到限制可以在扩展内移动的实现)响应此查询而产生除以零错误,因为假设它试图分3通过 0在执行限制和意识到 3 % 2 = 1 之前作为扩展的一部分?这可能变得很重要,例如,扩展是在一个小表上但结果——当与一个大表连接并基于大表中的数据进行限制时——最终限制了所有行要求除以零。

如果 t 有数百万行,并且最后一个查询是通过表扫描执行的,那么当遇到一个具有零值的偶数 x 时,是否允许实现在接近末尾发现除以零之前返回前几百万个结果你的?是否需要缓冲?

还有更糟糕的情况,考虑一下这个,这取决于语义可能会破坏 bool 短路或在限制中需要四值 bool 逻辑:
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

看起来这个值可能应该是一个错误,因为它取决于一个错误结果的空性或非空性,但采用这些语义似乎会禁止优化器在此处短路表扫描。此存在查询是否需要证明存在一个非底部行,或者还需要证明不存在底部行?

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

最佳答案

我使用过的所有 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 中的所有行,不管他们的商是多少。

此外,我再次阅读您的问题并意识到我没有讨论 where条款(耻辱!)。 where子句,或 predicate , 应始终在计算列之前应用。

想想这个查询:
select x, y, x/y as quot from t where x%2 = 0

如果我们有记录 (3,0),它将应用 where条件,并检查是否 3 % 2 = 0 .它没有,因此它不会在列计算中包含该记录,并将其保留在原处。

关于sql - SQL标准中错误值的处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1140860/

相关文章:

collections - Haskell "collections"语言设计

generics - Java 数组协方差是否违反 Liskov 替换原则?

java - 编译器 + 类间引用 : how does javac do quickly what C++ compilers do slowly?

php - Symfony2 删除记录实体问题

sql - 如何删除 PostgreSQL 中的数组元素?

php - MySQL 加盟亏本

powershell - PowerShell v2 Server 2003-找不到路径-路径确实存在

sql - 提高 UPDATE WHERE sql 查询的性能

javascript - "Uncaught ReferenceError: fail is not defined."为什么会出现这种情况?

python - 当信号处理程序中遇到异常时,如何使 Django 信号处理程序不会静默失败?