Oracle中的NULL(八)

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

          最近在論壇上經(jīng)常看到,很多人提出和NULL有關(guān)的問題。NULL其實是數(shù)據(jù)庫中特有的類型,Oracle中很多容易出現(xiàn)的錯誤都是和NULL有關(guān)的。

          打算簡單的總結(jié)一下NULL的相關(guān)知識。

          這一篇描述一下在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是否相等得到的結(jié)果一定是NULL。從唯一約束的特點也可以看到,對于建立了唯一約束的列,Oracle允許插入多個NULL值,這時因為Oracle不認為這些NULL是相等的。

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

          表已創(chuàng)建。

          SQL> INSERT INTO T VALUES (1);

          已創(chuàng)建 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);

          已創(chuàng)建 1 行。

          SQL> INSERT INTO T VALUES (NULL);

          已創(chuàng)建 1 行。

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

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

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

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

          已創(chuàng)建 1 行。

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

          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 © 林光炎

          主站蜘蛛池模板: 商河县| 大冶市| 共和县| 常德市| 新丰县| 当阳市| 建昌县| 韶关市| 黄大仙区| 波密县| 都安| 互助| 乐亭县| 宝清县| 七台河市| 万载县| 霍山县| 延津县| 大竹县| 株洲县| 安达市| 邯郸县| 华蓥市| 泰安市| 兰西县| 申扎县| 南澳县| 磴口县| 蒙山县| 固阳县| 雷州市| 山西省| 濮阳市| 离岛区| 宁城县| 济宁市| 仁寿县| 泊头市| 南部县| 和静县| 遵化市|