1

我有一个关于 SQL 标准的问题,希望 SQL语言律师能提供帮助。

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

我有一个表,t,(只有)两列,x每一y列都是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

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

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

还有更糟糕的情况,考虑一下这个,这取决于语义可能会破坏布尔短路或在限制中需要四值布尔逻辑:

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

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

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

4

1 回答 1

1

All implementations of SQL that I've worked with treat a division by 0 as an immediate NaN or #INF. The division is supposed to be handled by the front end, not by the implementation itself. The query should not bottom out, but the result set needs to return NaN in this case. Therefore, it's returned at the same time as the result set, and no special warning or message is brought up to the user.

At any rate, to properly deal with this, use the following query:

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

To answer your last question, this statement:

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

Would return this:

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

So, your exists would find all the rows in t, regardless of what their quotient was.

Additionally, I was reading over your question again and realized I hadn't discussed where clauses (for shame!). The where clause, or predicate, should always be applied before the columns are calculated.

Think about this query:

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

If we had a record (3,0), it applies the where condition, and checks if 3 % 2 = 0. It does not, so it doesn't include that record in the column calculations, and leaves it right where it is.

于 2009-07-17T12:00:07.373 回答