广告广告
  加入我的最爱 设为首页 风格修改
首页 首尾
 手机版   订阅   地图  繁体 
您是第 2927 个阅读者
 
发表文章 发表投票 回覆文章
  可列印版   加为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.050027 second(s),query:15 Gzip disabled
本站由 瀛睿律师事务所 担任常年法律顾问 | 免责声明 | 本网站已依台湾网站内容分级规定处理 | 连络我们 | 访客留言