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

PHP 操作 Oracle 8/9/10g/11g/12c/19c:OCI8 擴充功能完整函數參考與實戰範例

     編輯:關於SqlServer

環境需求

  • Oracle Client Libraries (Instant Client 或完整 Client) 安裝於 PHP 執行環境。
  • 環境變數正確設定:

ORACLE_HOME=/opt/oracle/instantclient_19_18
ORACLE_SID=ORCL
LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH
NLS_LANG=AMERICAN_AMERICA.AL32UTF8
  • PHP 編譯/安裝時啟用 `--with-oci8` (或 `docker-php-ext-install oci8`)。
  • Web 伺服器執行身分 (www-data, apache, nginx) 需具備上述環境變數 (在 systemd / apache envvars / php-fpm pool 設定)。

核心連線函數

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),避免轉換損耗與亂碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數用途備註
oci_connect()建立連線 (預設重用)同一腳本同一帳號/字串回傳相同資源
oci_pconnect()持久連線 (跨請求重用)減少連線開銷,注意連線池上限
oci_new_connect()強制建立新連線隔離交易/Session 狀態
oci_close()關閉連線持久連線不會真正關閉,歸還池中