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

PHP 操作 Oracle LOB 大物件完整實戰指南(BLOB/CLOB/BFILE)

     編輯:PHP 相關知識

為什麼需要 LOB?

VARCHAR2 最大 4000 位元組(約 2000 中文字),超過時有兩種方案:多欄位拆分或使用 LOB。LOB 支援 4GB,分三類:

  • CLOB:字元大物件(文字)
  • BLOB:二進位大物件(圖片、檔案)
  • BFILE:外部檔案指標(資料存檔案系統,資料庫只存路徑)
關鍵差異:MySQL 的 TEXT/BLOB 可直接像一般欄位操作;Oracle LOB 屬特殊型別,不可在 INSERT 直接賦值、不可用 LIKE 查詢,必須用 OCI 函數配合描述符操作。

操作流程六步驟(以 BLOB 圖片上傳為例)

建表結構

CREATE TABLE PICTURES (
    ID NUMBER,
    DESCRIPTION VARCHAR2(100),
    MIME VARCHAR2(128),
    PICTURE BLOB
);

CREATE SEQUENCE PIC_SEQ;  -- ID 自動遞增

插入流程

<?php
$conn = OCILogon($user, $password, $SID);

// 1. 分析 INSERT,用 EMPTY_BLOB() 產生空定位符,RETURNING 取回
$stmt = OCIParse($conn, "INSERT INTO PICTURES (id, description, picture) 
    VALUES (pic_seq.NEXTVAL, '$description', EMPTY_BLOB()) 
    RETURNING picture INTO :PICTURE");

// 2. 建立本地 LOB 物件描述符
$lob = OCINewDescriptor($conn, OCI_D_LOB);  // BLOB 用 OCI_D_LOB,CLOB 用 OCI_D_CLOB

// 3. 綁定 LOB 物件到 SQL 定位符
OCIBindByName($stmt, ':PICTURE', &$lob, -1, OCI_B_BLOB);

// 4. 執行 INSERT
OCIExecute($stmt);

// 5. 寫入資料(檔案用 savefile,字串用 save)
if ($lob->savefile($lob_upload)) {
    OCICommit($conn);
    echo "上傳成功<br>";
} else {
    echo "上傳失敗<br>";
}

// 6. 釋放資源
OCIFreeDesc($lob);
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
注意:LOB 欄位至少需 1 字元,save()/savefile() 前必須確保資料非空,否則 Oracle 報錯。

讀取流程(簡易版:OCI_RETURN_LOBS)

<?php
$conn = OCILogon($user, $password, $SID);
$stmt = OCIParse($conn, "SELECT * FROM PICTURES WHERE ID=$pictureid");
OCIExecute($stmt);

// 關鍵:第三參數 OCI_RETURN_LOBS 直接把 LOB 值放入結果陣列
if (OCIFetchInto($stmt, $result, OCI_ASSOC + OCI_RETURN_LOBS)) {
    header("Content-type: " . stripslashes($result['MIME']));
    echo stripslashes($result['PICTURE']);
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>

呼叫方式:<img src="getpicture.php?pictureid=99" alt="Oracle LOB 圖片">

查詢流程(DBMS_LOB.INSTR)

LOB 不支援 LIKE,需用 Oracle 內建套件 DBMS_LOB:

CREATE TABLE ARTICLES (
    ID NUMBER,
    TITLE VARCHAR2(100),
    CONTENT CLOB
);

<?php
$conn = OCILogon($user, $password, $SID);
// DBMS_LOB.INSTR(LOB定位符, 搜尋字串, 起始位置, 第N次出現) > 0 表示找到
$stmt = OCIParse($conn, "SELECT * FROM ARTICLES 
    WHERE DBMS_LOB.INSTR(CONTENT, 'PHP中文用戶', 1, 1) > 0");
OCIExecute($stmt);

if (OCIFetchInto($stmt, $result, OCI_ASSOC + OCI_RETURN_LOBS)) {
    // 處理結果...
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>

DBMS_LOB 常用函數速查

函數用途
DBMS_LOB.INSTR搜尋子字串位置(如上例)
DBMS_LOB.SUBSTR擷取子字串
DBMS_LOB.LENGTH取得 LOB 長度
DBMS_LOB.APPEND追加資料
DBMS_LOB.ERASE清除部分資料

BFILE 特殊說明

  • 建立時用 OCI_D_FILE、綁定用 OCI_B_FILE
  • 只支援 savefile() 方法,資料實際存檔案系統
  • 需在資料庫建立 DIRECTORY 物件對應實體路徑

總結

Oracle LOB 雖操作較 MySQL 複雜,但掌握「描述符→本地物件→綁定→執行→讀寫→釋放」六步驟,即可處理任意大小二進位/文字資料。查詢時善用 DBMS_LOB 套件彌補 SQL 限制。

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