2009-07-16 51 views
1

我有一個關於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

回答

1

我一直在使用的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檢查。它沒有,所以它不包括在列計算中的記錄,並將它保留在原來的位置。