Oracle中的NULL(八)

          Posted on 2009-06-29 10:59 林光炎 閱讀(1715) 評論(0)  編輯  收藏 所屬分類: ORACLE

          最近在論壇上經常看到,很多人提出和NULL有關的問題。NULL其實是數據庫中特有的類型,Oracle中很多容易出現的錯誤都是和NULL有關的。

          打算簡單的總結一下NULL的相關知識。

          這一篇描述一下在SQL和PLSQL中一些處理NULL的一些問題。

          Oracle中的NULL(一):http://yangtingkun.itpub.net/post/468/244434

          Oracle中的NULL(二):http://yangtingkun.itpub.net/post/468/245107

          Oracle中的NULL(三):http://yangtingkun.itpub.net/post/468/245259

          Oracle中的NULL(四):http://yangtingkun.itpub.net/post/468/245697

          Oracle中的NULL(五):http://yangtingkun.itpub.net/post/468/247492

          Oracle中的NULL(六):http://yangtingkun.itpub.net/post/468/251496

          Oracle中的NULL(七):http://yangtingkun.itpub.net/post/468/258467


          8\![ Q!x;]$Yf0

          NULL的最大的特點就是兩個NULL是不相等的。如果用等號來判斷兩個NULL是否相等得到的結果一定是NULL。從唯一約束的特點也可以看到,對于建立了唯一約束的列,Oracle允許插入多個NULL值,這時因為Oracle不認為這些NULL是相等的。

          SQL> CREATE TABLE T (ID NUMBER, CONSTRAINT UN_T UNIQUE(ID));

          表已創建。

          SQL> INSERT INTO T VALUES (1);

          已創建 1 行。

          SQL> INSERT INTO T VALUES (1);
          | Pw6I)A#P,x_0INSERT INTO T VALUES (1)
          +h:w|3~ N0*
          LCB-P#b{$C0ERROR 位于第 1 行:
          f9i vJ Y%T0ORA-00001: 違反唯一約束條件 (YANGTK.UN_T)


          &rSq _0P7QvYN0SQL> INSERT INTO T VALUES (NULL);

          已創建 1 行。

          SQL> INSERT INTO T VALUES (NULL);

          已創建 1 行。

          但是有的時候,Oracle會認為NULL是相同的,比如在GROUP BY和DISTINCT操作中。這個時候,Oracle會認為所有的NULL都是一類的。

          還有一種情況,就是在DECODE函數中。如果表達式為DECODE(COL, NULL, 0, 1),那么如果COL的值為NULL,Oracle會認為這種情況與第二個參數的NULL值相匹配,會返回0。不過這里只是給人感覺NULL值是相等的,Oracle在實現DECODE函數的時候,仍然是通過IS NULL的方式進行的判斷。

          對于大多數的常用函數來說,如果輸入為NULL,則輸出也是NULL。NVL、NVL2、DECODE和||操作是個例外。他們在輸入參數為NULL的時候,結果可能不是NULL。不過歸結其原因是因為,這些函數都有多個參數,當多個參數不全為NULL時,結果可能不是NULL,如果輸入參數均為NULL,那么得到的輸出結果也是NULL。

          NULL還有一個特點,就是一般聚集函數不會處理NULL值。不管是MAX、MIN、AVG還是SUM,這些聚集函數都不會處理NULL。注意這里說的不會處理NULL,是指聚集函數會直接忽略NULL值記錄的存在。除非是聚集函數處理的列中包含的全部記錄都是NULL,這種情況下,上面這些聚集函數會返回NULL值。

          SQL> DELETE T WHERE ID = 1;

          已刪除 1 行。

          SQL> SELECT NVL(TO_CHAR(ID), 'NULL') FROM T;

          NVL(TO_CHAR(ID),'NULL')ITPUB個人空間 Z,I Pa;o~)t/Tm7L
          ----------------------------------------
          L B d-f-A/o*c0NULLITPUB個人空間(C"}5Q5A#L#t
          NULL

          SQL> SELECT MAX(ID) FROM T;

          MAX(ID)
          !C Cs"Ys5|'`0----------


          G_S.c d5mk)O#c0SQL> SELECT AVG(ID) FROM T;

          AVG(ID)ITPUB個人空間*O.Ylk0OU(Oy4Dq$vQr
          ----------


          RFf+Lf{] y0SQL> INSERT INTO T VALUES (1);

          已創建 1 行。

          聚集函數中比較特殊的是COUNT,第一個特殊點是COUNT不會返回NULL值,即使表中沒有記錄,或者COUNT(COL)中,COL列的記錄全為NULL,COUNT也會返回0值而不是NULL。第二個特殊點就是COUNT(*)或COUNT(常量)的形式。這種形式使得COUNT可以計算包含NULL記錄在內的記錄總數。

          SQL> SELECT COUNT(*), COUNT(1), COUNT('A'), COUNT(ID), COUNT(NULL) FROM T;

          COUNT(*) COUNT(1) COUNT('A') COUNT(ID) COUNT(NULL)ITPUB個人空間-NNOH2z
          ---------- ---------- ---------- ---------- -----------
          ;s t:O8t3o.y0t0 3 3 3 1 0

          最后簡單說一下AVG,AVG(COL)等價于SUM(COL)/COUNT(COL),不等價于SUM(COL)/COUNT(*):

          SQL> SELECT AVG(ID), SUM(ID)/COUNT(ID), SUM(ID)/COUNT(*) FROM T;

          AVG(ID) SUM(ID)/COUNT(ID) SUM(ID)/COUNT(*)
          6~{9O*mL9C7c)p0---------- ----------------- ----------------
          6@:[S'L&k\&V9{VR0 1 1 .333333333


          posts - 104, comments - 33, trackbacks - 0, articles - 0

          Copyright © 林光炎

          主站蜘蛛池模板: 南开区| 铜陵市| 宜君县| 榕江县| 仪陇县| 海丰县| 大庆市| 余江县| 迭部县| 图们市| 和静县| 绥宁县| 吴旗县| 嵩明县| 海原县| 日土县| 松桃| 屏东市| 和平区| 和龙市| 轮台县| 巴马| 洛扎县| 淅川县| 大田县| 吉木乃县| 甘泉县| 台前县| 喀喇沁旗| 黄大仙区| 宣恩县| 体育| 广宁县| 天气| 定襄县| 通海县| 张家口市| 永善县| 泾川县| 呼伦贝尔市| 青川县|