廣告廣告
  加入我的最愛 設為首頁 風格修改
首頁 首尾
 手機版   訂閱   地圖  簡體 
您是第 2928 個閱讀者
 
發表文章 發表投票 回覆文章
  可列印版   加為IE收藏   收藏主題   上一主題 | 下一主題   
b8502806 手機
數位造型
個人文章 個人相簿 個人日記 個人地圖
小人物
級別: 小人物 該用戶目前不上站
推文 x0 鮮花 x4
分享: 轉寄此文章 Facebook Plurk Twitter 複製連結到剪貼簿 轉換為繁體 轉換為簡體 載入圖片
推文 x0
[SQL][討論] [分享] SQL 程式的應用 ─「值述語」
我將一系列相關連的一元布林述語 (可測試運算元的邏
輯值或 NULL 值) 稱作 "值述語" (valued predicate)
。其中 IS NULL 已是 SQL 的一部份, 但邏輯 IS 述語
則是 SQL-92 新增的述語, 在本書撰寫期間尚未有實作
產品支援 IS 述語。

IS NULL 述語

透過 IS NULL 述語測試欄位 NULL 值的語法如下:

================================================
::= IS
[NOT] NULL
================================================

這是測試一個運算式是否為 NULL 的唯一方法, SQL-86
與後續 SQL 版本的標準內都包含這個述語。SQL-92
標準還進一步延伸讓它可以接受以 【 資料列值建構子】代替單一欄位或量值運算
式。相信當 SQL 實作產品接受其他資料列運算式時,
也將開始支援這個延伸版述語。若 R 資料列裡的所有
值都為 NULL 值, 則 R IS NULL 為 TRUE;否則為 FA
LSE。若碰上資料列上 NULL 值與非 NULL 值參雜狀況,
則依下表定義傳回結果, 其中 【Degree】 代表資料
列運算式上的欄位數量。

運算式 R IS NULL R IS NOT NULL NOT R IS NULL NOT R IS NOT NULL Degree = 1         NULL TRUE FALSE FALSE TRUE No NULL FALSE TRUE TRUE FALSE Degree > 1         全為 NULLs TRUE FALSE FALSE TRUE 有些是 NULLs FALSE FALSE TRUE TRUE No NULLs FALSE TRUE TRUE FALSE

請注意 若 (且唯若) R 只有一個欄位 (Degree = 1) ,
則 R IS NOT NULL 與 NOT R IS NULL 的結果會一樣。
這也打破了NOT 置入述語時的通例。以下是一些範例:

================================================
NOT (NULL, NULL, NULL) IS NULL = FALSE
NOT (NULL, NULL, NULL) IS NOT NULL = TRUE
(1, NULL, 3) IS NOT NULL = FALSE
(NULL, NULL, NULL) IS NULL = TRUE
(NULL, NULL, NULL) IS NOT NULL = FALSE
NOT (1, 2, 3) IS NULL = TRUE
NOT (1, NULL, 3) IS NULL = TRUE
NOT (1, NULL, 3) IS NOT NULL = TRUE
NOT (NULL, NULL, NULL) IS NULL = FALSE
NOT (NULL, NULL, NULL) IS NOT = TURE
===============================================

[NULL 的來源]

記住 NULL 從何而來很重要。不只是欄位上可能會出現
NULL, 加總函數遇上空集合、OUTER JOIN (外部連結)
、碰上 NULL 的算術運算式... 等等都會傳回 NULL。
這些結構通常會出現在檢視表上的某個欄位上。

IS [NOT]{ TRUE | FALSE | UNKNOWN } 述語


本述語測試條件真偽值 TRUE、FALSE、或 UNKNOWN, 並
傳回 TRUE 或 FALSE。語法如下:

================================================
::=
  [ IS [ NOT ] ]

::= TRUE | FALSE | UNKNOWN

::=
  |  
================================================

如您所預見, IS NOT 運算式相等於
NOT (IS ), 所以述語可依下表定義:

IS 條件 TRUE FALSE UNKNOWN TRUE TRUE FALSE FALSE FALSE FALSE TRUE FALSE UNKNOWN FALSE FALSE TRUE

若您熟悉 Chris Date 的某些文章, 您可能會記得他的
MAYBE(x) 述語不同於 ANSI (x) IS NOT FALSE 述語,
但反而相等於 (x) IS UNKNOWN 述語。Date 的述語排
除了述語裡所有條件皆為 TRUE 的狀況。

Date 指出要用英語詢問條件式問題很難。現借用 Date
的一個範例 (Date 1990), 試想該如何找出可能為程式
設計師、生日早於 1941 年 1 月 18 日、薪水低於 $50
,000 的員工。這個問題的敘述在 "可能為" 說法上有點
模糊不清 -- 只要是程式設計師就好呢, 還是這 3 個條
件都要符合?讓我們假設我們希望有些不確定, 那麼透
過本述語, 答案相當容易求出:

================================================
SELECT *
FROM Employees
WHERE (job = 'Programmer'
  AND dob < CAST (񟬅-01-18' TO DATE)
  AND salary < 50000) IS NOT UNKNOWN;
================================================

它也可以轉換成適用於 SQL-89 的版本:

================================================
SELECT *
  FROM Employees
WHERE (job = 'Programmer'
  AND dob < CAST (񟬅-01-18' TO DATE)
  AND salary < 50000)
  OR (job IS NULL
    AND dob < CAST (񟬅-01-18' TO DATE)
    AND salary < 50000)
  OR (job = 'Programmer'
    AND dob IS NULL
    AND salary < 50000)
  OR (job = 'Programmer'
    AND dob < CAST (񟬅-01-18' TO DATE)
    AND salary IS NULL)
  OR (job IS NULL
    AND dob IS NULL
    AND salary < 50000)
  OR (job IS NULL
    AND dob < CAST (񟬅-01-18' TO DATE)
    AND salary IS NULL)
  OR (job = 'Programmer'
    AND dob IS NULL
    AND salary IS NULL)
  OR (job IS NULL
    AND dob IS NULL
    AND salary IS NULL);
================================================

本問題在於各種 NULL 值與非 NULL 值的組合都得測試
。由於涉及 3 個述語, 這使得我們必須檢查 (2^3) =
8 種組合。若改用 IS NOT UNKNOWN 述語, 就不需要煩
心這些組合, 只要注意最後邏輯值即可。

--- 本篇完


[ 此文章被andyz在2005-05-18 20:28重新編輯 ]



獻花 x0 回到頂端 [樓 主] From:台灣數位聯合 | Posted:2004-11-10 21:21 |

首頁  發表文章 發表投票 回覆文章
Powered by PHPWind v1.3.6
Copyright © 2003-04 PHPWind
Processed in 0.069104 second(s),query:15 Gzip disabled
本站由 瀛睿律師事務所 擔任常年法律顧問 | 免責聲明 | 本網站已依台灣網站內容分級規定處理 | 連絡我們 | 訪客留言