PHP Conference Japan 2024

oci_parse

(PHP 5, PHP 7, PHP 8, PECL OCI8 >= 1.1.0)

oci_parse準備要執行的 Oracle 陳述式

說明

oci_parse(資源 $connection, 字串 $sql): 資源|false

使用 connection 準備 sql 並返回陳述式識別碼,該識別碼可與 oci_bind_by_name()oci_execute() 和其他函式一起使用。

可以使用 oci_free_statement() 或將變數設為 null 來釋放語句識別碼。

參數

connection(連線)

一個 Oracle 連線識別碼,由 oci_connect()oci_pconnect()oci_new_connect() 返回。

sql

SQL 或 PL/SQL 語句。

SQL 語句不應該以分號 (";") 結尾。PL/SQL 語句應該以分號 (";") 結尾。

傳回值

成功時傳回語句控制代碼,錯誤時傳回 false

範例

範例 #1 SQL 語句的 oci_parse() 範例

<?php

$conn
= oci_connect('hr', 'welcome', 'localhost/XE');

// 解析語句。請注意,SQL 語句中沒有最後的分號
$stid = oci_parse($conn, 'SELECT * FROM employees');
oci_execute($stid);

echo
"<table border='1'>\n";
while (
$row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
echo
"<tr>\n";
foreach (
$row as $item) {
echo
" <td>" . ($item !== null ? htmlentities($item, ENT_QUOTES) : "&nbsp;") . "</td>\n";
}
echo
"</tr>\n";
}
echo
"</table>\n";

?>

範例 #2 PL/SQL 語句的 oci_parse() 範例

<?php

/*
在執行 PHP 程式之前,請先在
SQL*Plus 或 SQL Developer 中建立一個預存程序:

CREATE OR REPLACE PROCEDURE myproc(p1 IN NUMBER, p2 OUT NUMBER) AS
BEGIN
p2 := p1 * 2;
END;

*/

$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$p1 = 8;

// 解析 PL/SQL 程式時,字串結尾應有分號
$stid = oci_parse($conn, 'begin myproc(:p1, :p2); end;');
oci_bind_by_name($stid, ':p1', $p1);
oci_bind_by_name($stid, ':p2', $p2, 40);

oci_execute($stid);

print
"$p2\n"; // 顯示 16

oci_free_statement($stid);
oci_close($conn);

?>

注意事項

備註:

此函數*不會*驗證 sql。 唯一能確定 sql 是否為有效 SQL 或 PL/SQL 陳述式的方法是執行它。

另請參閱

新增備註

使用者貢獻的備註 5 則備註

interloper at ukr dot net
9 年前
如果您要在變數中使用 PL/SQL

<?php
$query
= "begin null; end;";
$stid = oci_parse($conn, "$query");
?>

或者

<?php
$stid
= oci_parse($conn, "begin null; end;");
?>
michael dot virnstein at brodos dot de
17 年前
如果查詢是在函式內完成的,那麼這是一種在每個腳本中僅解析一次查詢的簡潔方法。

<?php
function querySomething($conn, $id)
{
static
$stmt;

if (
is_null($stmt)) {
$stmt = oci_parse($conn, 'select * from t where pk = :id');
}

oci_bind_by_name($stmt, ':id', $id, -1);

oci_execute($stmt, OCI_DEFAULT);

return
oci_fetch_array($stmt, OCI_ASSOC);

}

?>

使用靜態變數,語句句柄在函數終止後不會被關閉。這對於在例如迴圈中被呼叫的函數來說非常有用。可惜的是,這只適用於靜態 SQL。如果您有動態 SQL,您可以執行以下操作

<?php

函數 querySomething($conn, $data)
{
靜態
$stmt = 陣列();

$first = 真;

$query = 'select * from t';

foreach (
$data as $key => $value) {
if (
$first) {
$first = 假;
$query .= ' where ';
} else {
$query .= ' and ';
}

$query .= "$key = :b$key";
}

$queryhash = md5($query);

if (
is_null($stmt[$queryhash])) {
$stmt[$queryhash] = oci_parse($conn, $query);
}

foreach (
$data as $key => $value) {
// 不要使用 $value,因為我們在此綁定記憶體位址。
// 這將導致每次綁定在 foreach 之後都指向相同的值
oci_bind_by_name($stmt[$queryhash], ":b$key", $data[$key], -1);
}

oci_execute($stmt[$queryhash], OCI_DEFAULT);

return
oci_fetch_array($stmt[$queryhash], OCI_ASSOC);

}

?>
kurt at kovac dot ch
20 年前
對於那些在錯誤檢查方面遇到問題的人,我注意到在很多網站上,人們試圖使用 OCIParse 檢查語句控制代碼中的錯誤訊息。 由於語句控制代碼 ($sth) 還未建立,因此您需要使用 OCIParse 檢查資料庫控制代碼 ($dbh) 是否有任何錯誤。 例如

不要使用

<?php
$stmt
= OCIParse($conn, $query);
if (!
$stmt) {
$oerr = OCIError($stmt);
echo
"擷取程式碼 1:".$oerr["message"];
exit;
}
?>

而是使用

<?php
$stmt
= OCIParse($conn, $query);
if (!
$stmt) {
$oerr = OCIError($conn);
echo
"Fetch Code 1:".$oerr["message"];
exit;
}
?>

希望這對某些人有幫助。
egypt at nmt dot edu
21 年前
MySQL 不在意 LIKE 子句周圍使用哪種引號,但 ociexecute 會針對以下情況發出錯誤:
ociexecute(): OCIStmtExecute: ORA-00904: "NM": 無效的識別名稱
例如以下程式碼:
<?php
$sql
= "SELECT * FROM addresses "
. "WHERE state LIKE \"NM\""; // 錯誤!
$stmt = ociparse($conn, $sql);
ociexecute($stmt);
?>

如果只使用單引號就沒問題
. "WHERE state LIKE 'NM'";
但我覺得有趣的是,ociparse 沒有任何提示
falundir at gmail dot com
13 年前
當您想要呼叫在其主體內執行 DML 查詢(插入、更新、刪除)的儲存函式(並想讀取其結果)時,您不能使用「select your_stored_function(:param1, :param2) from dual」,因為您會收到「ORA-14551: 無法在查詢內執行 DML 操作」錯誤。

為了呼叫此類函式並取得其結果,您需要將其包裝到具有 OUT 參數的巢狀程序中,如下所示:

DECLARE
PROCEDURE caller(return_value OUT NUMBER) AS
BEGIN
return_value := your_stored_function(:param1, :param2);
END;
BEGIN
caller(:return_value);
END;

並綁定到 :return_value 變數以取得函式的結果。
To Top