確認資料存在 → 建立 Directory 物件 → 授權 → 建立預存程序 → 執行匯出 → 驗證檔案
COL fdesc FOR A30
SELECT fid, fname, fdesc FROM eygle_blob;
FID FNAME FDESC
--- ----------- --------------------
1 ShaoLin.jpg 少林寺-易經經
2 DaoYing.jpg 倒映
CONNECT / AS SYSDBA
CREATE OR REPLACE DIRECTORY BLOBDIR AS 'D:\oradata\Pic';
GRANT READ, WRITE ON DIRECTORY BLOBDIR TO eygle;
關鍵點:Directory 是邏輯別名,映射作業系統實際路徑;需 READ/WRITE 權限分別授予。
CONNECT eygle/eygle
CREATE OR REPLACE PROCEDURE eygle_dump_blob(
piname IN VARCHAR2, -- 來源檔名(資料庫 fname)
poname IN VARCHAR2 -- 目標檔名(作業系統)
) IS
l_file UTL_FILE.FILE_TYPE;
l_buffer RAW(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob BLOB;
l_blob_len INTEGER;
BEGIN
-- 1. 讀取 BLOB 到變數
SELECT fpic INTO l_blob FROM eygle_blob WHERE fname = piname;
l_blob_len := DBMS_LOB.GETLENGTH(l_blob);
-- 2. 開啟作業系統檔案(二進位寫入)
l_file := UTL_FILE.FOPEN('BLOBDIR', poname, 'wb', 32767);
-- 3. 迴圈讀寫(分塊處理大物件)
WHILE l_pos < l_blob_len LOOP
DBMS_LOB.READ(l_blob, l_amount, l_pos, l_buffer);
UTL_FILE.PUT_RAW(l_file, l_buffer, TRUE); -- TRUE = 自動 flush
l_pos := l_pos + l_amount;
END LOOP;
-- 4. 關閉檔案
UTL_FILE.FCLOSE(l_file);
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.IS_OPEN(l_file) THEN
UTL_FILE.FCLOSE(l_file);
END IF;
RAISE; -- 重拋異常保留堆疊
END;
/
| 套件/函數 | 用途 | 關鍵參數 |
|---|---|---|
| DBMS_LOB.GETLENGTH | 取得 BLOB 位元組長度 | l_blob |
| DBMS_LOB.READ | 讀取 BLOB 片段 | (lob, amount, offset, buffer) |
| UTL_FILE.FOPEN | 開啟檔案 | (dir, filename, 'wb', max_linesize) |
| UTL_FILE.PUT_RAW | 寫入 RAW 資料 | (file, buffer, autoflush) |
| UTL_FILE.FCLOSE | 關閉檔案 | (file) |
-- 匯出前
HOST LS -L D:\oradata\Pic
-- total 7618
-- -rwxrwxrwa 1 ... 2131553 Apr 19 10:12 DaoYing.jpg
-- -rwxrwxrwa 1 ... 1768198 Apr 19 10:12 ShaoLin.jpg
-- 執行匯出
EXEC eygle_dump_blob('ShaoLin.jpg', '01.jpg');
EXEC eygle_dump_blob('DaoYing.jpg', '02.jpg');
-- 匯出後
HOST LS -L D:\oradata\Pic
-- total 15236
-- -rwxrwxrwa 1 Administrators SYSTEM 1768198 Apr 26 07:16 01.jpg
-- -rwxrwxrwa 1 Administrators SYSTEM 2131553 Apr 26 07:19 02.jpg
-- 原檔保留,新檔建立成功
Oracle 12c+ 可使用 DBMS_LOB.CREATETEMPORARY + DBMS_LOB.OPEN + DBMS_LOB.LOADFROMFILE 搭配 BFILENAME,或直接用 SQL Developer / Data Pump 匯出 LOB 資料。