1. SQL 指令 (NULL)
DROP TABLE USER1.TESTNULL; / CREATE TABLE USER1.TESTNULL ( ID NUMBER(3,0) DEFAULT 0 NOT NULL, NAME CHAR(10) NULL, ADDRESS NVARCHAR2(20) NULL, CONSTRAINT PK_TESTNULL PRIMARY KEY ( ID ) ); / INSERT INTO TESTNULL(ID, NAME, ADDRESS) VALUES (1, 'JASPER', 'TAIPEI'); -- NAME 及 ADDRESS 給預設值, 也就是 NULL INSERT INTO TESTNULL(ID) VALUES (2); -- NAME 給預設值, ADDRESS 填入 5 個 bytes 的空白 INSERT INTO TESTNULL(ID, ADDRESS) VALUES (3, LPAD(' ', 5, ' ')); -- NAME 及 ADDRESS 給空字串. INSERT INTO TESTNULL(ID, NAME, ADDRESS) VALUES (4, '', ''); / -- 情境1 ------------------------- PROMPT -- [情境1] -------------------------; SELECT ID , '[' || NAME || ']' AS NAME1 , '[' || ADDRESS || ']' AS ADDRESS1 FROM TESTNULL; -- 情境2 ------------------------- PROMPT -- [情境2] -------------------------; SELECT ID , LENGTH(NAME) AS LEN1 , LENGTH(ADDRESS) AS LEN2 -- CASE NAME WHEN NULL THEN -1 ELSE LENGTH(NAME) END AS LEN1 , -- CASE ADDRESS WHEN NULL THEN -1 ELSE LENGTH(ADDRESS) END AS LEN2 FROM TESTNULL; -- 情境3.1 ------------------------- PROMPT -- [情境3.1] -------------------------; -- 預期結果: 2, 3, 4 SELECT ID, NAME, ADDRESS FROM TESTNULL WHERE NAME IS NULL; -- 情境3.2 ------------------------- PROMPT -- [情境3.2] -------------------------; -- 預期結果 2, 3, 4 ? => 錯, 答案是查不到資料 SELECT ID, NAME, ADDRESS FROM TESTNULL WHERE NAME = ''; -- 情境4.1 ------------------------- PROMPT -- [情境4.1] -------------------------; -- 預期結果: 2, 4 SELECT ID, NAME, ADDRESS FROM TESTNULL WHERE ADDRESS IS NULL; -- 情境4.2 ------------------------- PROMPT -- [情境4.2] -------------------------; -- 預期結果 2, 4 ? => 錯, 答案是查不到資料 SELECT ID, NAME, ADDRESS FROM TESTNULL WHERE ADDRESS = ''; /
2. 輸出結果 (NULL)
Table USER1.TESTNULL 已刪除. Table USER1.TESTNULL 已建立. 1 資料列 已插入. 1 資料列 已插入. 1 資料列 已插入. 1 資料列 已插入. -- [情境1] ------------------------- ID NAME1 ADDRESS1 ---------- ------------ ---------------------- 1 [JASPER ] [TAIPEI] 2 [] [] 3 [] [ ] 4 [] [] -- [情境2] ------------------------- ID LEN1 LEN2 ---------- ---------- ---------- 1 10 6 2 3 5 4 -- [情境3.1] ------------------------- ID NAME ADDRESS ---------- ---------- -------------------- 2 3 4 -- [情境3.2] ------------------------- 未選取資料列 -- [情境4.1] ------------------------- ID NAME ADDRESS ---------- ---------- -------------------- 2 4 -- [情境4.2] ------------------------- 未選取資料列
4. 結論 (NULL)
不論是 CHAR or VARCHAR2 只要欄位是允許 NULL:
(1) 在 INSERT, UPDATE 時, 填入空字串會被轉為 NULL 值.
(2) 在 WHERE 條件裡, 依 參考文件3, 4, 5, 任何欄位內容值 與 NULL 作比較, 會得到 Unknown 的結果.
本例中的第2, 4筆的 ADDRESS 欄位內容值為 NULL, 與空字串作比較 (不確定是否有將空字串轉為 NULL), 其結果應該是 Unknown, 所以不會被顯示出來.
也就是只能用 IS NULL, 或者用反向的 IS NOT NULL, 而不能用 = '' 作為條件判斷.
5. 參考文件
- 01. 黑暗執行緒, KB-詭異的NOT IN查詢,原來是NULL搞鬼
- 02. 黑暗執行緒, ORACLE, 你把空字串怎麼了?
- 03. 黑暗執行緒, KB-當 WHERE AND/OR 條件遇上 NULL
- 04. Oracle Help Center, Database SQL Reference: Nulls
- 05. Oracle Help Center, SQL Language Reference: Nulls
沒有留言:
張貼留言