Oracle的null說明


  假設有一張表格table1

col_a

col_b

 (空格)

1

 

2

 

3

 

 

a

 

 

 

 

 

 

 

 

 

 

 

 

 

查詢:

  select * from table1 where col_a = ''    --0條記錄

  select * from table1 where col_a is null    --3條記錄

  select * from table1 where col_a !='a'    --1條記錄

  解釋:null的意義:沒有值,不等價於任何值,是一個未知數,當null作為條件進行操作時,就不能用"="(雖然語法沒有錯),即不能定值判斷,應該使用is null 或者 is not null

  除is null/ is not null語句外,對null的操作均不會出現返回在結果中

 

插入:

  插入空字符串的時候會自動轉化為null,在Oracle中沒有空字符串,只有null,例如:

  insert into table1 values(null, null);    -- 插入NULL,插入成功

  insert into table1 values('a', '');    -- 第二個字段類型為int型,但還是能插入成功,再次證明,’’ 被當作了null處理,如果是字符串,執行會報錯

 

函數:

在使用AVG,MAX,SUM,COUNT等函數時,為NULL的紀錄往往會被忽略。

例如:

  select AVG(col_b) from table1;  -- 結果為 2 ,NULL的紀錄行忽略掉了

  select MAX(col_b) from table1;  -- 結果為 3

  select SUM(col_b) from table1;  -- 結果為 6

  select COUNT(col_b) from table1;  -- 結果為 3

  select COUNT(col_a) from table1;  -- 結果為 2

  select COUNT(*) from table1;  -- 結果為 5

 

排序:

  select * from table1 order by address    -- null值會排在后面

  select * from table1 order by address desc    -- null值會排在前面

  Order by排序時缺省認為null是最大值,ASC升序則被排在最后,而DESC降序則排在最前

  解決:如果要改變排序方式,可以:

    1. 使用 nvl 函數,例如在排序中使用ORDER BY NVL(FIELD, '0')

    2. 使用其它函數,例如:decode,case

    3. nulls first或nulls last(注:Nulls first:表示null值的記錄將排在最前;Nulls last:表示null值的記錄將排在最后),例:

      select * from table1 order by aac001 asc nulls first    --null值始終放在最前面
      select * from table1 order by aac001 desc nulls last    --null值始終放在最后面

 

計算:

  對NULL的=、!=、>、<、>=、<=等操作的結果都為NULL。

  對NULL進行+、-、*、/等操作的結果也都為NULL。

 

其他:

AND操作:

AND

TRUE

FALSE

NULL

TRUE

TRUE

FALSE

NULL

FALSE

FALSE

FALSE

FALSE

NULL

NULL

FALSE

NULL

 

 

 

 

 

 

 

 

OR操作:

OR

TRUE

FALSE

NULL

TRUE

TRUE

TRUE

TRUE

FALSE

TRUE

FALSE

NULL

NULL

TRUE

NULL

NULL

 

 

 

 

 

 

 

 

NOT操作:

NOT TRUE

NOT FALSE

NOT NULL

FALSE

TRUE

NULL

 

 

 

 

  解釋:NULL是未知的,但目前NULL的類型為布爾類型,因此NULL只有可能是TRUE或者FALSE中的一個。所以,這邊可以把NULL看成是(TRUE OR FALSE)

 

NULL的深入分析:

  (參考:https://blog.csdn.net/lotusyangjun/article/details/6177169)

 

  一、NULL是數據庫中特有的數據類型,當一條記錄的某列為NULL,則表示該列的值是未知的、是不確定的。既然是未知的,就有無數種的可能性。因此,NULL並不是一個確定的值。

  判斷一個字段是否為NULL,應該用IS NULL或IS NOT NULL,而不能用‘=’。對NULL的判斷只能定性,即是不是NULL(IS NULL/IS NOT NULL),而不能定值。簡單的說,由於NULL存在着無數的可能,因此兩個NULL不是相等的關系,同樣也不能說兩個NULL就不相等,或者比較兩個NULL的大小,這些操作都是沒有意義,得不到一個確切的答案的。因此,對NULL的=、!=、>、<、>=、<=等操作的結果 都是未知的,也就算說,這些操作的結果仍然是NULL。

  同理,對NULL進行+、-、*、/等操作的結果也是未知的,所以也是NULL。

  所以,很多時候會這樣總結NULL,除了IS NULL、IS NOT NULL以外,對NULL的任何操作的結果還是NULL。

  由於引入了NULL,在處理邏輯過程中一定要考慮NULL的情況。同樣的,數據庫中的布爾值的處理,也是需要考慮NULL的情況,這使得布爾值從原來的TRUE、FALSE兩個值變成了TRUE、FALSE和NULL三個值:

  TRUE AND NULL:NULL

  TRUE OR NULL:TRUE

  FALSE AND NULL:FALSE

  FALSE OR NULL:NULL

  NULL AND TRUE:NULL

  NULL OR TRUE:TRUE

  NULL AND FALSE:FALSE

  NULL OR FALSE:NULL

  NULL AND NULL:NULL

  NULL OR NULL:NULL

  NOT TRUE:FALSE

  NOT FALSE:TRUE

  NOT NULL:NULL

  注:NULL是未知的,但是目前NULL的類型是布爾類型,因此NULL只有可能是TRUE或者FALSE中的一個。所以,這邊可以把NULL看成是(TRUE OR FALSE)。

  如果只是給出一個NULL,那么它是可以代表任意的類型的。

 

  二、以上面的表為例:

    select * from table1 where col_a in ('a',' ',null);

    查詢結果為2條,col_a in ('a',' ',null); 等價於col_a ='a' or col_a = ' ' or col_a = null,當查到第一條時,等價於false or true or null,所以總的查詢結果為2條。

    select * from table1 where col_a not in ('a',' ',null);

    查詢結果為0條,col_a not in ('a',' ',null); 等價於col_a !='a' and col_a != ' ' and col_a != null,當查到第一條時,等價於true and false and null,結果為false,所以總的查詢結果為0條。

 

  三、空字符串差不多就是和null等價 

  例如:SELECT 1 FROM DUAL WHERE '' = ''  --查詢結果為空

    SELECT 1 FROM DUAL WHERE '' IS NULL;  --結果為1

    SELECT DUMP(''), DUMP(NULL) FROM DUAL;  --結果為null null

    SELECT NULL || 'A', 'B' || NULL, NULL || NULL FROM DUAL;  --結果為A  B  null

  從NULL的存儲格式上解釋。Oracle在存儲數據時,先是存儲這一列的長度,然后存儲列數據本身。而對於NULL,只包含一個FF,沒有數據部分。簡單的說,Oracle用長度FF來表示NULL。

  由於Oracle在處理的數據存儲的時候盡量避免0的出現,因此,認為這里FF表示的是長度為0也是有一定道理的。或者從另一方面考慮,NULL只有一個長度,而沒有數據部分。

  而對於字符串來說,不管是長度為0的字符串還是沒有任何數據的字符串,所代表的含義都是一個空字符串。從這一點上講,空字符串就是NULL也是有一定的道理的。

  如果認為空字符串是字符形式的NULL,那么||操作的結果就不難理解了。

  最后需要說明的是,不要將ORACLE里面的空字符串’’與C里面的空字符串””混淆。C里面的空字符串並非不不含任何數據,里面還包含了一個字符串結束符。C語言中的空字符串””對應Oracle中ASCII表中的0值,既CHR(0)。但CHR(0)是一個確定的值,它顯然不是NULL。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM