| 函數 | 用途 | 備註 |
oci_connect() | 建立連線 (預設重用) | 同一腳本同一帳號/字串回傳相同資源 |
oci_pconnect() | 持久連線 (跨請求重用) | 減少連線開銷,注意連線池上限 |
oci_new_connect() | 強制建立新連線 | 隔離交易/Session 狀態 |
oci_close() | 關閉連線 | 持久連線不會真正關閉,歸還池中 |
SQL 執行流程
$conn = oci_connect('user', 'pass', '//host:1521/service_name');
$stid = oci_parse($conn, 'SELECT * FROM employees WHERE department_id = :did');
oci_bind_by_name($stid, ':did', $dept_id);
oci_execute($stid); // 預設自動提交,OCI_DEFAULT 可延遲提交
while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
print_r($row);
}
oci_free_statement($stid);
oci_close($conn);
關鍵函數分類
綁定與定義
oci_bind_by_name():綁定 PHP 變數至預留位置,支援 `IN`/`OUT`/`INOUT`、型別常數 (`SQLT_CHR`, `SQLT_INT`, `SQLT_BLOB` 等)。
oci_define_by_name():定義 SELECT 欄位對應 PHP 變數 (效能優於 `oci_fetch_array`)。
LOB/FILE 處理
oci_new_descriptor($conn, OCI_D_LOB):建立 LOB 記述子。
$lob->save($data) / $lob->load() / $lob->read($len) / $lob->write($data) / $lob->free()。
oci_lob_copy(), oci_lob_is_equal(), oci_lob_import() (從檔案)。
交易控制
oci_commit($conn)、oci_rollback($conn)。
oci_execute($stid, OCI_DEFAULT):不自動提交,需手動 `oci_commit`。
中繼資料
oci_num_fields($stid)、oci_field_name($stid, $n)、oci_field_type($stid, $n)、oci_field_precision()、oci_field_scale()。
其他
oci_row_count($stid):DML 影響列數。
oci_error($resource):取得最後錯誤陣列 (code, message, offset, sqltext)。
oci_set_prefetch($stid, $rows):預先抓取列數減少網路往返。
oci_statement_type($stid):SELECT/INSERT/UPDATE/DELETE/BEGIN/CALL。
實戰範例:CLOB 寫入與預存程序呼叫
CLOB 插入 (RETURNING 子句)
$sql = "INSERT INTO docs (id, content) VALUES (:id, EMPTY_CLOB()) RETURNING content INTO :clob";
$stid = oci_parse($conn, $sql);
$clob = oci_new_descriptor($conn, OCI_D_LOB);
oci_bind_by_name($stid, ':id', $id);
oci_bind_by_name($stid, ':clob', $clob, -1, OCI_B_CLOB);
oci_execute($stid, OCI_DEFAULT);
$clob->save("大量文字內容...");
oci_commit($conn);
$clob->free();
呼叫預存程序 (IN/OUT 參數)
$stid = oci_parse($conn, "BEGIN pkg_hr.update_salary(:emp_id, :new_sal, :err_code); END;");
oci_bind_by_name($stid, ':emp_id', $emp_id);
oci_bind_by_name($stid, ':new_sal', $new_sal);
oci_bind_by_name($stid, ':err_code', $err_code, 20); // OUT 參數需指定長度
oci_execute($stid);
echo "Error code: $err_code";
效能與最佳實踐
- 使用連線池 (`oci_pconnect` + `oci8.max_persistent` / `oci8.persistent_timeout`)。
- 預先抓取 (`oci_set_prefetch`) 減少往復。
- 定義而非抓取陣列 (`oci_define_by_name`) 降低記憶體複製。
- 批次處理:`oci_bind_array_by_name` + `oci_execute_many` (需 Oracle 12c+)。
- 錯誤處理:永遠檢查 `oci_error()`,不要忽略回傳值。
- 字元集:資料庫/客戶端/PHP 腳本統一 UTF-8 (AL32UTF8),避免轉換損耗與亂碼。
- 上一篇文章: SQL Server DATALENGTH 函數完整說明:取得運算式實際位元組長度
- 下一篇文章: SQL Server 進階操作指南:索引策略、核心 DML、聚合函數、字串/日期處理與郵件發送
Copyright ©
程式碼之家 All Rights Reserved