从 PHP 调用 Oracle 包中存在的函数/过程

Posted

技术标签:

【中文标题】从 PHP 调用 Oracle 包中存在的函数/过程【英文标题】:Calling a function/procedure present inside an Oracle package from PHP 【发布时间】:2011-06-12 00:58:45 【问题描述】:

我正在使用 php-PDO 和 Oracle 11g。我正在使用具有许多功能和存储过程的 Oracle 包。现在,当我从 sql*plus 或 sql developer IDE 调用其中一个函数时,我运行此命令来获取结果集。

   select package_name.function_name(param1,param2) from dual

它工作正常并返回我的结果集。现在,当我这样做时,我会从 PDO 异常处理中得到错误。 PHP端的代码如下所示,

$stmt = "select package_name.function_name (?,?) from dual";
$res = $this->ConnOBJ->prepare($stmt);
$param1 = '1';
$param2 = null;
$result->bindParam(1,$param1);
$result->bindParam(2,$param2);
$result->execute();  

我得到了一个正在记录到我的日志文件中的异常。

Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 904 OCIStmtExecute: ORA-00904: "PACKAGE_NAME"."FUNCTION_NAME"": invalid identifier  (/var/www/php-5.3.3/ext/pdo_oci/oci_statement.c:146)' in /opt/web/dir/ora_class.php:209 Stack trace: #0 /opt/web/dir/ora_class.php(209): PDOStatement->execute() #1 /opt/web/dir/ora_class.php(298): dbPDO->execPackage() #2 main   thrown in /opt/web/dir/ora_class.php on line 209

我是否以错误的方式传递查询?还是我绑定参数的方式不对?

更新

我现在已经将数据传递给 Oracle,并找到了如何传递空值。我现在的代码是

$stmt = "select package_name.function_name(?,?) from dual";
$res = $this->ConnOBJ->prepare($stmt);

$param1 = 1;
$param2 = null;

$res->bindParam(1,$param1,PDO::PARAM_INT);
$res->bindParam(2,$param2,PDO::PARAM_NULL);

$res->execute();
var_dump($res->fetchAll());

现在当我传递数据时,我得到了错误

PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 932 OCIStmtFetch: ORA-00932: inconsistent datatypes: expected CHAR got DTYCWD  (/var/www/php-5.3.3/ext/pdo_oci/oci_statement.c:467)' in /opt/web/dir/ora_class.php:216 Stack trace: #0 /opt/web/dir/ora_class.php(216): PDOStatement->fetchAll() #1 /opt/web/dir/ora_class.php(305): dbPDO->execPackage() #2 main   thrown in /opt/web/dir/ora_class.php on line 216

我确保所有类型都是正确的,但我仍然收到同样的错误。我什至删除了 null 值并传入了一个字符串,并将 pdo 类型更改为 PDO::PARAM_STR,但它仍然给了我错误。

【问题讨论】:

好吧,我已经查询了架构中的其他表,它们返回了一个结果集,因此凭据有效。 包中的函数? @macha - 是的。在包中贴出函数的规范 Justin 我刚刚粘贴了正在调用的函数。 @macha - 好的。您发布的函数似乎需要 4 个参数,而不是 2 个。此外,您能否发布 MY 表的定义(或者至少四个 %TYPE 声明解析为什么? 【参考方案1】:

函数接受一个参数还是两个参数?在 SQL*Plus 中,您传递了两个参数。在 PHP 中,您只传递一个。如果函数需要两个参数并且没有只接受一个参数的重载方法,则会出现此错误。

【讨论】:

好吧,我正在尝试通过另一个参数传递 null。我只为一个参数传递值。我该如何处理? @macha - 既然您为第二个参数传递了 NULL,那么您得到的错误完全相同? 嗯,不,我实际上找到了绑定空值的方法,现在我得到了一个不同的错误。 @macha - 好的。您是否使用新错误更新了您的帖子?出现的错误似乎与您只传递一个参数时遇到的错误相同。 贾斯汀,我刚刚更新了帖子,你能看一下吗?【参考方案2】:

我不再使用 PDO,我将使用 OCI 驱动程序。谢谢大家的帮助。

【讨论】:

【参考方案3】:

这是一个类似问题的答案链接 [LINK]:https://***.com/a/57558306/7897970

最好的


//Your connection details
$conn = oci_connect($username, $password, '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))' );

/* Your query string; you can use oci_bind_by_name to bind parameters or just pass the variable in it*/

 $query = "begin :cur := functionName('".$param1."','".$param2."','".$param3."'); end;";
      $stid = oci_parse($conn, $query); 
      $OUTPUT_CUR = oci_new_cursor($conn);
      oci_bind_by_name($stid, ':cur', $OUTPUT_CUR, -1, OCI_B_CURSOR);
      oci_execute($stid); 
      oci_execute($OUTPUT_CUR);
      oci_fetch_all($OUTPUT_CUR, $res);

// To get your result  
      var_dump($res);


【讨论】:

以上是关于从 PHP 调用 Oracle 包中存在的函数/过程的主要内容,如果未能解决你的问题,请参考以下文章

oracle 包中定义全局变量

如何使用 java.sql 包中的 rs.getSQLXML() 函数从 Oracle 数据库中获取 XMLType 列?

如何php调用oracle存储过程返回的是一个结果集,该怎么从php页面中吧数据循环输出呀

函数

从 apex 页面进程调用 pl/sql 函数

如何从包中删除过程或函数