VARCHAR2 最大 4000 位元組(約 2000 中文字),超過時有兩種方案:多欄位拆分或使用 LOB。LOB 支援 4GB,分三類:
關鍵差異:MySQL 的 TEXT/BLOB 可直接像一般欄位操作;Oracle LOB 屬特殊型別,不可在 INSERT 直接賦值、不可用 LIKE 查詢,必須用 OCI 函數配合描述符操作。
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 報錯。
<?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 圖片">
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.INSTR | 搜尋子字串位置(如上例) |
| DBMS_LOB.SUBSTR | 擷取子字串 |
| DBMS_LOB.LENGTH | 取得 LOB 長度 |
| DBMS_LOB.APPEND | 追加資料 |
| DBMS_LOB.ERASE | 清除部分資料 |
OCI_D_FILE、綁定用 OCI_B_FILEsavefile() 方法,資料實際存檔案系統DIRECTORY 物件對應實體路徑Oracle LOB 雖操作較 MySQL 複雜,但掌握「描述符→本地物件→綁定→執行→讀寫→釋放」六步驟,即可處理任意大小二進位/文字資料。查詢時善用 DBMS_LOB 套件彌補 SQL 限制。