首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle PL/SQL 讀取 BLOB 欄位實戰:Directory 物件、UTL_FILE 與 DBMS_LOB 完整流程

     編輯:Oracle 資料庫基礎

完整操作流程圖

確認資料存在 → 建立 Directory 物件 → 授權 → 建立預存程序 → 執行匯出 → 驗證檔案

步驟 1:確認資料存在

COL fdesc FOR A30
SELECT fid, fname, fdesc FROM eygle_blob;

FID FNAME       FDESC
--- ----------- --------------------
1   ShaoLin.jpg 少林寺-易經經
2   DaoYing.jpg 倒映

步驟 2:建立 Directory 物件(需 SYSDBA)

CONNECT / AS SYSDBA
CREATE OR REPLACE DIRECTORY BLOBDIR AS 'D:\oradata\Pic';
GRANT READ, WRITE ON DIRECTORY BLOBDIR TO eygle;

關鍵點:Directory 是邏輯別名,映射作業系統實際路徑;需 READ/WRITE 權限分別授予。

步驟 3:建立匯出預存程序

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;
/

關鍵 API 解析

套件/函數用途關鍵參數
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)

步驟 4:執行與驗證

-- 匯出前
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
-- 原檔保留,新檔建立成功

大檔案處理優化建議

  • 分塊大小:32767 為 UTL_FILE 最大緩衝,可調整
  • 平行處理:極大檔案考慮 DBMS_LOB.CONVERTTOCLOB + 外部表
  • 權限管理:Directory 路徑需 Oracle 服務帳號具備 OS 讀寫權限
  • 異常處理:務必在 EXCEPTION 中關閉檔案,避免檔案鎖定

現代替代方案

Oracle 12c+ 可使用 DBMS_LOB.CREATETEMPORARY + DBMS_LOB.OPEN + DBMS_LOB.LOADFROMFILE 搭配 BFILENAME,或直接用 SQL Developer / Data Pump 匯出 LOB 資料。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved