1. SQL 指令 (NOT NULL)
DROP TABLE USER1.TESTNOTNULL;
/
CREATE TABLE USER1.TESTNOTNULL (
ID NUMBER(3,0) DEFAULT 0 NOT NULL,
NAME CHAR(10) DEFAULT ' ' NOT NULL,
ADDRESS NVARCHAR2(20) DEFAULT ' ' NOT NULL,
CONSTRAINT PK_TESTNOTNULL PRIMARY KEY ( ID )
);
/
INSERT INTO TESTNOTNULL(ID, NAME, ADDRESS)
VALUES (1, 'JASPER', 'TAIPEI');
-- NAME 及 ADDRESS 給預設值.
INSERT INTO TESTNOTNULL(ID)
VALUES (2);
-- NAME 給預設值, ADDRESS 填入 5 個 bytes 的空白
INSERT INTO TESTNOTNULL(ID, ADDRESS)
VALUES (3, LPAD(' ', 5, ' '));
/
-- 情境1 -------------------------
PROMPT -- [情境1] -------------------------;
SELECT ID
, '[' || NAME || ']' AS NAME1
, '[' || ADDRESS || ']' AS ADDRESS1
FROM TESTNOTNULL;
-- 情境2 -------------------------
PROMPT -- [情境2] -------------------------;
-- 3 筆資料的 NAME 長度都是 10 --> 因為 CHAR(10), 會被補空白.
-- 3 筆資料的 ADDRESS 長度不同 --> 因為 VARCHAR2(20), 不會被補空白. 以實際資料值為準
SELECT ID
, LENGTH(NAME) AS LEN1
, LENGTH(ADDRESS) AS LEN2
FROM TESTNOTNULL;
/
-- INSERT 失敗情境_A -------------------------
PROMPT -- [INSERT 失敗情境_A] -------------------------;
-- NAME 填入空字串, ADDRESS 填入 3 個 bytes 的空白 --> 會失敗
INSERT INTO TESTNOTNULL(ID, NAME, ADDRESS)
VALUES (4, '', LPAD(' ', 3, ' ') );
-- INSERT 失敗情境_B -------------------------
PROMPT -- [INSERT 失敗情境_B] -------------------------;
-- NAME 給預設值, ADDRESS 填入空字串 --> 會失敗
INSERT INTO TESTNOTNULL(ID, ADDRESS)
VALUES (5, '' );
/
2. 輸出結果 (NOT NULL)
Table USER1.TESTNOTNULL 已刪除.
Table USER1.TESTNOTNULL 已建立.
1 資料列 已插入.
1 資料列 已插入.
1 資料列 已插入.
-- [情境1] -------------------------
ID NAME1 ADDRESS1
---------- ------------ ----------------------
1 [JASPER ] [TAIPEI]
2 [ ] [ ]
3 [ ] [ ]
-- [情境2] -------------------------
ID LEN1 LEN2
---------- ---------- ----------
1 10 6
2 10 1
3 10 5
-- [INSERT 失敗情境_A] -------------------------
命令的第 37 行開始發生錯誤 -
INSERT INTO TESTNOTNULL(ID, NAME, ADDRESS)
VALUES (4, '', LPAD(' ', 3, ' ') )
錯誤報告 -
ORA-01400: 無法將空值插入 ("USER1"."TESTNOTNULL"."NAME")
-- [INSERT 失敗情境_B] -------------------------
命令的第 42 行開始發生錯誤 -
INSERT INTO TESTNOTNULL(ID, ADDRESS)
VALUES (5, '' )
錯誤報告 -
ORA-01400: 無法將空值插入 ("USER1"."TESTNOTNULL"."ADDRESS")
4. 結論 (NOT NULL)
不論是 CHAR or VARCHAR2 只要欄位是 不允許 NULL, 就不能在 INSERT, UPDATE 時, 填入空字串, 因為空字串被視為 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


沒有留言:
張貼留言