Oracle - LOB(大物件資料型別)
一、簡介
在ORACLE資料庫中,LOB(Large Objects(大物件))是用來儲存大量的二進位制和文字資料的一種資料型別。在 Oracle8i 中開始提供 LOB 欄位,在 Oracle10g 前最多隻能儲存 4G 資料,從 Oracle10g 開始,可以儲存 8-128T 的資料,取決於你的資料庫的塊大小。
LOB又分為兩種型別:內部LOB型別:將資料以位元組流的形式儲存在資料庫的內部。因而,內部LOB的許多操作都可以參與事務,也可以像處理普通資料一樣對其進行備份和恢復操作。如:
BLOB:二進位制大物件。定義一個 BLOB 變數,用於儲存大量的二進位制資料(如影象、視訊、音訊等),該二進位制大物件儲存於資料庫中。
CLOB:字元型大物件(單位元組字元資料)。定義一個 CLOB 變數,用於儲存超長的文字資料,該字元型大物件儲存於資料庫中。
NCLOB:字元型大物件(多位元組國家字元資料)。定義一個 NCLOB 變數,用於儲存超長的文字資料,該字元型大物件儲存於資料庫中。
外部LOB型別:在資料庫內僅儲存資料在作業系統中的位置資訊,而資料的實體以外部檔案的形式存在於作業系統的檔案系統中。因而,該型別所表示的資料是隻讀的,不參與事務。如:
BFILE:二進位制檔案。定義一個 BFILE 變數,它指向作業系統的一個檔案,Oracle 會將其視為二進位制資料進行處理。
二、內部LOB(BLOB/CLOB/NCLOB)
在 Oracle 中,儲存在 LOB 列中的不是實際的資料,而是該LOB欄位的定位器,即指向 LOB 資料在資料庫中實際儲存的位置(不是記憶體中)的指標。而要對某一 LOB 的值進行訪問和維護操作,首先得獲取到這個 LOB 指標,然後使用 DBMS_LOB 包中提供的函式和過程處理實際的 LOB 資料。
1、建立
通過系統函式 EMPTY_CLOB(),得到一個空的 LOB 指標,但這個指標在此時不指向磁碟中的任何位置,也沒有任何 LOB 資料。它可用於初始化 LOB 變數,或者在 INSERT 或 UPDATE 語句中用於將LOB列進行初始化(根據表的定義確定儲存的位置),但不填充資料,如果需要使用該初始化後的 LOB,需要再一次從表中查詢它出來。
INSERT INTO lob_demo (lob_id, lob_content) VALUES (100,EMPTY_CLOB());
2、寫入沒有指向資料庫實際儲存位置的 LOB 不能被寫入;更新 LOB 時必須要用for update 鎖定
DECLARE
lob_object CLOB;
amount BINARY_INTEGER;
offset INTEGER;
content_str VARCHAR2(100);
BEGIN
--插入一行新的記錄來建立一個新的 LOB 定位器(沒有指向資料庫實際儲存位置的 LOB 不能被寫入)
INSERT INTO lob_demo (lob_id, lob_content) VALUES (100, EMPTY_CLOB());
--檢索出上面建立的 LOB 的定位器(更新 LOB 必須要用 for update 鎖定)
SELECT lob_content INTO lob_object FROM lob_demo WHERE lob_id=100 for update;
content_str := 'Follow I-75 across the Mackinac Bridge.';
amount := LENGTH(content_str); -- 要寫入的字元數
offset := 1; -- LOB 中開始寫入的位置
DBMS_LOB.OPEN(lob_object, DBMS_LOB.LOB_READWRITE); -- 開啟 LOB(不是嚴格必須的)
DBMS_LOB.WRITE(lob_object, amount, offset, content_str); -- 開始寫入
DBMS_LOB.CLOSE(lob_object); -- 關閉
END;
3、讀取
DECLARE
lob_object CLOB;
content_str VARCHAR2(300);
read_amount BINARY_INTEGER;
offset INTEGER;
BEGIN
--檢索先前插入的 LOB 定位器
SELECT lob_content INTO lob_object FROM lob_demo WHERE lob_id =100;
offset := 1;
read_amount := 200;
DBMS_LOB.READ(lob_demo, read_amount, offset, content_str);
IF read_amount = 200 THEN ----如果實際讀了200個字元,更新偏移量,繼續嘗試讀取.
DBMS_OUTPUT.PUT_LINE(content_str);
offset := offset + read_amount;
DBMS_LOB.READ(lob_demo, read_amount, offset, content_str);
DBMS_OUTPUT.PUT_LINE(content_str);
ELSE --如果實際沒讀夠200個,則表示已經讀取完了
DBMS_OUTPUT.PUT_LINE(content_str);
END IF;
END;
三、外部LOB(BFILE)
在 PL/SQL 中操作 BFILE,其實也是操作 LOB 指標。只是對於 BFILE 的指標來說,它指向的 BFILE 資料在資料庫外。所以,一個 BFILE 列的兩行,可以儲存指向同一個檔案的 BFILE 指標。
和BLOB,CLOB,NCLOB三種大欄位型別相比,BFILE 有以下三點不同:
1) BFILE 的資料是儲存在作業系統檔案中的,而不是在資料庫中
2) BFILE 資料不參與事務處理,也就是說,BFILE 資料的改變不能被提交和回滾(但 BFILE 指標的改變是可以提交或回滾的)
3) 從 PL/SQL 中,只能讀取 BFILE 資料,而不能寫入。必須得在資料庫外先建立 BFILE 檔案,再建立 BFILE 指標
1、建立
BFILE 指標由目錄和檔名組成,將這兩部分資訊作為引數傳入 BFILENAME 函式,該函式會返回一個 BFILE 指標
一個 BFILE 指標只是簡單地將目錄和檔名聯合在一塊,而實際的目錄和檔案甚至可以不存在。所以,你可以建立一個目錄,它實際指向的路徑並不存在;再使用這個目錄建立一個 BFILE 指標
-- 第一步:
create directory bfile_data as '/usr/local/bfiledata'; --建立一個目錄
-- 第二步:
DECLARE
piece_bfile BFILE;
BEGIN
piece_bfile := BFILENAME('BFILE_DATA','test.jpg'); --建立一個BFILE指標
INSERT INTO bfile_demo (bfile_id, bifle_content) VALUES (100, piece_bfile); --儲存到表中
END;
2、讀取
DECLARE
bfile_object BFILE;
piece RAW(60);
amount BINARY_INTEGER := 60;
offset INTEGER := 1;
BEGIN
SELECT bifle_content INTO bfile_object FROM bfile_demo WHERE bfile_id = 100;
-- 開啟這個指標,讀取60個位元組,然後關閉它
DBMS_LOB.OPEN(bfile_object);
DBMS_LOB.READ(bfile_object, amount, 1, piece);
DBMS_LOB.CLOSE(bfile_object);
--16進位制顯示結果
DBMS_OUTPUT.PUT_LINE(RAWTOHEX(piece));
END;
3、轉換
BFILE 提供了一種從資料庫中訪問檔案系統中資料的方法,同時 ORACLE 也提供了從 BFILE 到 LOB 的方法:DBMS_LOB.LOADCLOBFROMBFILE和DBMS_LOB.LOADBLOBFROMBFILE
DECLARE
piece_bfile BFILE := BFILENAME('BFILE_DATA','test.jpg'); --建立一個BFILE指標
photo_blob BLOB;
BEGIN
SELECT bifle_content INTO photo_blob FROM bfile_demo WHERE bfile_id = 101;
DBMS_LOB.OPEN(photo_blob, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.OPEN(piece_bfile);
DBMS_LOB.LOADBLOBFROMFILE(photo_blob, piece_bfile, DBMS_LOB.LOBMAXSIZE, 1, 1);
DBMS_LOB.CLOSE(photo_blob);
DBMS_LOB.CLOSE(piece_bfile);
END;
四、Temporary LOBs
1、說明
Temporary LOB,它跟我們先前介紹的 LOB 不一樣,先前的可以稱之為 Persistent LOB。有時候,我們需要 Temporary LOB,就像其它型別的本地變數一樣,在會話中使用,而不用持久化到資料庫中。
Temporary LOB 的預設生存期是其所在的會話的生存期,但可以被手工釋放。使用 Temporary LOB,不會產生 REDO 和 UNDO 資訊,所以能提供更好的效能。
和 Persistent LOB 一樣,Temporary LOB 資料也是儲存在資料庫中的,不要以為它是在記憶體中存在的。但 Temporary LOB 資料並不跟任何表的列相關聯,而是儲存在該會話所佔用的臨時表空間中。所以使用 Temporary LOB,你得保證臨時表空間足夠儲存它。
2、建立
有兩種建立方法,一種是使用系統過程 DBMS_LOB.CREATETEMPORARY 顯式建立,一種是直接賦值隱式建立。
顯式建立:
DBMS_LOB.CREATETEMPORARY (
-- 指定LOB定位符
lob_loc IN OUT NOCOPY [ BLOB | CLOB CHARACTER SET ANY_CS ],
-- 是否將LOB讀取到緩衝區
cache IN BOOLEAN,
-- 指定何時清除臨時LOB(DBMS_LOB.SESSION(10):會話結束時。DBMS_LOB.CALL(12):呼叫結束時)
dur IN PLS_INTEGER := DBMS_LOB.SESSION
);
隱式建立:DECLARE
temp_clob CLOB;
temp_blob BLOB;
BEGIN
--給 NULL 的 LOB 變數賦值
temp_clob := 'www.baidu.com';
temp_blob := HEXTORAW('7A');
END;
3、釋放
使用系統過程 DBMS_LOB.FREETEMPORARY 釋放 Temporary LOB
在 PL/SQL 中,若已被釋放掉的 Temporary LOB 指標被賦值給另一個 LOB 指標,則這個指標也被釋放
系統函式 DBMS_LOB.ISTEMPORARY 可以判斷一個 LOB 指標是否指向 Temporary LOB 資料
-- 返回值:1 表示入參為 Temporary LOB 指標;0 表示入參是 persistent LOB 指標
DBMS_LOB.ISTEMPORARY (lob_loc IN [ BLOB | CLOB CHARACTER SET ANY_CS ]) RETURN INTEGER;
4、管理
1) 和 persistent LOB 不同,Temporary LOB 不支援事務管理、一致性讀取、回滾等等,所以你應該注意以下幾點:
* 當處理 Temporary LOB 發生錯誤時,你必須釋放該 LOB,然後重新進行該處理
* 由於不支援一致性讀取和回滾,所以你不能將多個 LOB 指標都指向同一個 Temporary LOB 資料
* 若一個使用者想要修改一個 Temporary LOB 資料,但該資料與另一個 LOB 指標關聯,則會發生該 Temporary LOB 資料的拷貝(deep copy)。那麼指向該 LOB 資料的其它指標將會看到不同的資料。為了降低 deep copy,當將 Temporary LOB 作為引數傳遞時,使用 NOCOPY 線索;
* 通過呼叫 DBMS_LOB.COPY 過程,可以將 Temporary LOB 資料持久化到資料庫中
* 在一個會話中,Temporary LOB 指標是唯一的。不能將一個指標從一個會話傳遞到另一個會話,使得相關聯的 LOB 資料在另一個會話中可用
2) 從 Oracle9i Database Release 1 開始,可以通過檢視 v$temporary_lobs 來檢視每個會話中有多少被快取的和未被快取的 LOBs。還可以通過資料字典 dba_segments 來檢視每個會話中 LOB 佔用的空間。
五、參考
http://blog.csdn.net/cunxiyuan108/article/details/6422387
相關文章
- Oracle 資料型別Oracle資料型別
- ORACLE物件型別表Oracle物件型別
- 【轉】ORACLE資料型別Oracle資料型別
- Oracle anydata資料型別Oracle資料型別
- ORACLE NUMBER資料型別Oracle資料型別
- Oracle資料型別對應Java型別Oracle資料型別Java
- Oracle OCP(19):資料型別Oracle資料型別
- Oracle的number資料型別Oracle資料型別
- ORACLE LOB大欄位維護Oracle
- 【LOB】Oracle Lob管理常用sqlOracleSQL
- JavaScript獲取物件資料型別JavaScript物件資料型別
- NumPy之:資料型別物件dtype資料型別物件
- Oracle字串資料型別簡述Oracle字串資料型別
- 【LOB】Oracle lob管理常用語句Oracle
- JS中資料型別、內建物件、包裝型別物件、typeof關係JS資料型別物件
- 從原始資料型別到值物件資料型別物件
- JavaScript筆記5:計時器、物件、基本資料型別、引用資料型別JavaScript筆記物件資料型別
- Oracle和sqlserver資料型別對應OracleSQLServer資料型別
- Oracle基本資料型別儲存格式淺析——RAW型別Oracle資料型別
- [20190531]lob型別pctversion 和 retention.txt型別
- 八大資料型別大資料資料型別
- JavaScript 基礎 (二) - 引用資料型別 (物件)JavaScript資料型別物件
- 資料型別與函式索引-Oracle篇資料型別函式索引Oracle
- 跟著大彬讀原始碼 - Redis 5 - 物件和資料型別(上)原始碼Redis物件資料型別
- 跟著大彬讀原始碼 - Redis 6 - 物件和資料型別(下)原始碼Redis物件資料型別
- 八大基本資料型別資料型別
- js資料型別之基本資料型別和引用資料型別JS資料型別
- 資料型別: 資料型別有哪些?資料型別
- 1.1. Oracle 資料庫使用者型別Oracle資料庫型別
- [20191219]oracle timestamp資料型別的儲存.txtOracle資料型別
- 如何檢視ORACLE的LOB(BLOB和CLOB)物件佔用的大小Oracle物件
- 第10章 物件和類——物件和類(六) 抽象資料型別物件抽象資料型別
- 大資料分析的型別有哪些大資料型別
- 區別值型別資料和引用型別資料型別
- Oracle資料庫高水位釋放——LOB欄位空間釋放Oracle資料庫
- 資料型別,型別轉換資料型別
- 阿里為何禁止在物件中使用基本資料型別阿里物件資料型別
- 細談Redis五大資料型別Redis大資料資料型別
- 資料型別資料型別