oci_parse

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

oci_parse准备 Oracle 语句以供执行

说明

oci_parse(resource $connection, string $sql): resource|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 oci_parse() 的 SQL 语句示例

<?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 oci_parse() 的 PL/SQL 语句示例

<?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
8 年前
如果你想在变量中使用 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
16 年前
一种在脚本中仅解析一次查询的巧妙方法,如果查询在函数内部完成

<?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

function querySomething($conn, $data)
{
static
$stmt = array();

$first = true;

$query = 'select * from t';

foreach (
$data as $key => $value) {
if (
$first) {
$first = false;
$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) 尚未创建,您需要检查数据库句柄 ($dbh) 以获取使用 OCIParse 的任何错误。例如

而不是

<?php
$stmt
= OCIParse($conn, $query);
if (!
$stmt) {
$oerr = OCIError($stmt);
echo
"Fetch Code 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
20 年前
虽然 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: cannot perform a DML operation inside a query”错误。

为了调用这样的函数并获取其结果,您需要将其包装到具有 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