使用PDO和PHP获取Oracle存储过程输出参数值的问题
PDO调用Oracle存储过程无法获取输出参数的解决办法
你的代码存在几个关键问题,导致输出参数$seller_id始终无法被赋值:
问题点
- bindParam传值而非引用:
queryProc里绑定参数时,你传的是$value[0]的值,但bindParam需要变量引用才能把存储过程的输出写回原变量。 - 连接提前关闭:
callProc的finally块直接把连接置空,存储过程执行后还没读取输出参数就断了连接。 - Oracle调用语法错误:用
call语法不适合带输出参数的Oracle存储过程,得用PL/SQL的BEGIN...END块。 - 参数类型不匹配:
$seller_id是数字,你却绑定成PDO::PARAM_STR,类型不对导致值无法正确返回。
修正后的代码
1. 调整Sql类的方法
public function queryProc($rawQuery, $params = array()) { $stmt = $this->conn->prepare($rawQuery); foreach ($params as $key => $param) { // 传递变量引用,bindParam需要这个才能修改原变量 $stmt->bindParam($key, $param[0], $param[1], $param[2]); } $stmt->execute(); return $stmt; } public function callProc($rawQuery, $params = array()) { try { return $this->queryProc($rawQuery, $params); } catch (PDOException $e) { echo $e->getMessage(); return null; } // 别在这里关连接,用析构函数自动处理 } // 析构函数自动关闭连接 public function __destruct() { $this->conn = null; }
2. 修改调用逻辑
$seller_id = 0; // 确保$token和$body_arr已正确赋值 $sql = new Sql(); // 用PL/SQL块调用存储过程 $stmt = $sql->callProc( 'BEGIN PKG_VISCLI.LOGIN(:usuario, :senha, :token, :codusur); END;', array( ':usuario' => array(&$body_arr['username'], PDO::PARAM_STR, 50), ':senha' => array(&$body_arr['password'], PDO::PARAM_STR, 50), ':token' => array(&$token, PDO::PARAM_STR, 50), // 改成INT类型,对应Oracle的number(4,0) ':codusur' => array(&$seller_id, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 4) ) ); // 执行完后$seller_id就有值了 echo $seller_id;
关键修改说明
- 引用传递:参数数组里每个变量前加
&,让bindParam能拿到变量引用,这样存储过程的输出才能写回$seller_id。 - 调用语法:换成
BEGIN...END块,这是Oracle调用带输出参数存储过程的标准方式。 - 参数类型:把
codusur的类型改成PDO::PARAM_INT,和Oracle里的number(4,0)匹配。 - 连接管理:移除
finally里的连接关闭,改用析构函数自动关闭,避免提前断开导致参数值读不到。
内容的提问来源于stack exchange,提问作者karam yakoub agha
相关产品推荐
相关产品推荐

