LOB欄位EMPTY_LOB和NULL的區別
前不久寫過一篇文章,描述如果表包含了觸發器,在透過IMP匯入資料的時候,原本的EMPTY_LOB將被轉化為NULL。有朋友在文章的回覆中問,EMPTY_LOB和NULL的區別,這裡就簡單描述一下。
包含觸發器的LOB表執行IMP導致EMPTY_LOB變為空:http://yangtingkun.itpub.net/post/468/495024
說實話,二者其實差別還是相當大的。一個表示的未知,另一個表示的空的大物件。需要注意空的大物件並不是空的概念:
SQL> CREATE TABLE T_LOB
2 (ID NUMBER,
3 NAME VARCHAR2(30),
4 CONTENTS CLOB);
表已建立。
SQL> INSERT INTO T_LOB
2 VALUES (1, 'TEST NULL', NULL);
已建立 1 行。
SQL> INSERT INTO T_LOB
2 VALUES (2, 'EMPTY LOB', EMPTY_CLOB());
已建立 1 行。
SQL> COMMIT;
提交完成。
SQL> COL CONTENTS FORMAT A30
SQL> SELECT *
2 FROM T_LOB
3 WHERE CONTENTS IS NULL;
ID NAME CONTENTS
---------- ------------------------------ ------------------------------
1 TEST NULL
使用IS NULL作為條件進行判斷,EMPTY_LOB是查詢不到的。
利用DBMS_LOB.GETLENGTH也可以看出二者的區別:
SQL> SELECT ID, NAME, DBMS_LOB.GETLENGTH(CONTENTS)
2 FROM T_LOB;
ID NAME DBMS_LOB.GETLENGTH(CONTENTS)
---------- ------------------------------ ----------------------------
1 TEST NULL
2 EMPTY LOB 0
從佔用空間上二者也有明顯的區別:
SQL> DELETE T_LOB WHERE ID = 2;
已刪除 1 行。
SQL> BEGIN
2 FOR I IN 1..10000 LOOP
3 INSERT INTO T_LOB
4 VALUES (1, 'TEST NULL', NULL);
5 END LOOP;
6 COMMIT;
7 END;
8 /
PL/SQL 過程已成功完成。
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T_LOB')
PL/SQL 過程已成功完成。
SQL> SELECT TABLE_NAME, NUM_ROWS, BLOCKS, AVG_ROW_LEN
2 FROM USER_TABLES
3 WHERE TABLE_NAME = 'T_LOB';
TABLE_NAME NUM_ROWS BLOCKS AVG_ROW_LEN
------------------------------ ---------- ---------- -----------
T_LOB 10001 28 13
SQL> TRUNCATE TABLE T_LOB;
表被截斷。
SQL> INSERT INTO T_LOB
2 VALUES (2, 'EMPTY LOB', EMPTY_CLOB());
已建立 1 行。
SQL> BEGIN
2 FOR I IN 1..10000 LOOP
3 INSERT INTO T_LOB
4 VALUES (2, 'EMPTY LOB', EMPTY_CLOB());
5 END LOOP;
6 COMMIT;
7 END;
8 /
PL/SQL 過程已成功完成。
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T_LOB')
PL/SQL 過程已成功完成。
SQL> SELECT TABLE_NAME, NUM_ROWS, BLOCKS, AVG_ROW_LEN
2 FROM USER_TABLES
3 WHERE TABLE_NAME = 'T_LOB';
TABLE_NAME NUM_ROWS BLOCKS AVG_ROW_LEN
------------------------------ ---------- ---------- -----------
T_LOB 10001 80 116
雖然EMPTY_LOB沒有包含LOB內容,但是LOB頭資訊已經存在,因此需要佔用不小的空間。
二者最大的區別在於,EMPTY_LOB雖然沒有LOB的內容,但是已經做好了插入LOB內容的準備,使用者獲取到LOB的頭資訊後就可以直接插入資料了:
SQL> TRUNCATE TABLE T_LOB;
表被截斷。
SQL> INSERT INTO T_LOB
2 VALUES (1, 'TEST NULL', NULL);
已建立 1 行。
SQL> INSERT INTO T_LOB
2 VALUES (2, 'EMPTY LOB', EMPTY_CLOB());
已建立 1 行。
SQL> COMMIT;
提交完成。
SQL> DECLARE
2 V_LOB CLOB;
3 BEGIN
4 SELECT CONTENTS
5 INTO V_LOB
6 FROM T_LOB
7 WHERE ID = 2
8 FOR UPDATE;
9 DBMS_LOB.WRITEAPPEND(V_LOB, 10, '0123456789');
10 COMMIT;
11 END;
12 /
PL/SQL 過程已成功完成。
SQL> DECLARE
2 V_LOB CLOB;
3 BEGIN
4 SELECT CONTENTS
5 INTO V_LOB
6 FROM T_LOB
7 WHERE ID = 1
8 FOR UPDATE;
9 DBMS_LOB.WRITEAPPEND(V_LOB, 10, '0123456789');
10 COMMIT;
11 END;
12 /
DECLARE
*
第 1 行出現錯誤:
ORA-06502: PL/SQL: 數字或值錯誤 : invalid LOB locator specified: ORA-22275
ORA-06512: 在 "SYS.DBMS_LOB", line 833
ORA-06512: 在 line 9
SQL> SELECT *
2 FROM T_LOB;
ID NAME CONTENTS
---------- ------------------------------ ------------------------------
1 TEST NULL
2 EMPTY LOB 0123456789
而對於NULL來說,顯然是不能直接修改的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-627538/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於mysql設定varchar 欄位的預設值''和null的區別,以及varchar和char的區別MySqlNull
- select * 和 select 所有欄位的區別
- [20181020]lob欄位的索引段.txt索引
- ORACLE LOB大欄位維護Oracle
- null 和 undefined 的區別NullUndefined
- null 和 undefined 的區別!NullUndefined
- undefined 和 null 區別?UndefinedNull
- null和undefined區別NullUndefined
- sql 統計多個欄位的和(如果欄位中含有 null 的處理)SQLNull
- JS 的型別(null 和 undefined 的區別)JS型別NullUndefined
- 2>/dev/null和>/dev/null 2>&1和2>&1>/dev/null的區別devNull
- javascrit中undefined和null的區別JavaUndefinedNull
- Object.create(null) 和 {} 的區別ObjectNull
- js中null和undefined的區別JSNullUndefined
- js中undefined和null的區別JSUndefinedNull
- [20181022]lob欄位的lobid來之那裡.txt
- [20210208]lob欄位與查詢的問題.txt
- [20181031]lob欄位與布隆過濾.txt
- json轉化保留null欄位JSONNull
- MySQL-去掉不為null的欄位MySqlNull
- sql語句修改欄位型別和增加欄位SQL型別
- MySQL中TEXT與BLOB欄位型別的區別MySql型別
- Python中none和null的區別詳解!PythonNoneNull
- mysql 空值(null)和空字元('')的區別MySqlNull字元
- NULL在oracle和mysql索引上的區別NullOracleMySql索引
- Mybatis-Plus 更新欄位為 NULLMyBatisNull
- LOB欄位相關概念(自動建立LOB索引段和重建索引方法)索引
- MySQL null值欄位是否使用索引的總結MySqlNull索引
- JavaScript中的“undefined、null”區別?JavaScriptUndefinedNull
- [重慶思莊每日技術分享]-重建LOB欄位上的IndexIndex
- MySQL:count(*) count(欄位) 實現上區別MySql
- Object.create(null) 和 {} 區別是什麼ObjectNull
- HTTP 頭部欄位 Cache Control max-age = 0 和 no-cache 的區別HTTP
- 關於mysql中欄位定義的型別int、tinyint區別MySql型別
- 【ORA-01555】Oracle LOB欄位匯出 報錯 ORA-01555Oracle
- Oracle 修改欄位型別和長度Oracle型別
- JavaScript undefined與null區別JavaScriptUndefinedNull
- 為什麼資料庫欄位要使用NOT NULL?資料庫Null
- PHP7 ?? 與 ?: 的作用和區別(null合併運算子, null條件運算子)PHPNull