【问题标题】:How is a Postgres "RAISE EXCEPTION" converted into a PDOException?Postgres“RAISE EXCEPTION”如何转换为 PDOException?
【发布时间】:2013-03-14 23:17:55
【问题描述】:

我试图找出“RAISE EXCEPTION”语句的哪些“部分”映射到 PDOException 的哪些“部分”。有人可以解释“谁”和“如何”执行此转换(或者更好的是,指向描述此转换的文档或执行此转换的源代码)?

更具体地说,我想知道是否有办法影响 SQLSTATUS 值(在我的测试中,它始终是“P0001”)和/或“ERROR:”值(它是消息的一部分并且始终为空)

我能做到的最好是:

使用 message = '' 引发异常,ERRCODE = 'UE001'

这在 PHP 方面给了我这样的消息:

错误:编号:UE001,详细信息:

但我对此不太满意。能够将“UE001”“放入”其中一个 PDOException 字段会很棒(因此我不必从消息字符串中解析它)。

我们将不胜感激。

【问题讨论】:

  • 始终显示您的代码和 PostgreSQL 版本。

标签: php postgresql exception


【解决方案1】:

使用PDOExceptioncode 属性获取SQLSTATE。见the documentation for PDOException

要控制由引发错误的 PL/PgSQL 函数生成的SQLSTATE,请使用RAISE ... SQLSTATE as per the documentation

当然,要使其正常工作,数据库驱动程序必须正确报告SQLSTATE。我已经验证 PDO 至少在 PHP 5.4.11 和 PostgreSQL 9.2 中执行此操作,根据以下可以使用 php 命令行可执行文件执行的独立示例代码:

<?php
$pdo = new PDO('pgsql:');

$sql = <<<EOD
CREATE OR REPLACE FUNCTION exceptiondemo() RETURNS void AS $$
BEGIN
  RAISE SQLSTATE 'UE001' USING MESSAGE = 'error message';
END;
$$ LANGUAGE plpgsql
EOD;

$sth = $pdo->prepare($sql);
if (!$sth->execute()) {
        die("Failed to create test function\n");
}

$sql = "SELECT exceptiondemo();";

$sth = $pdo->prepare($sql);
if (!$sth->execute()) {
        $ei = $sth->errorInfo();
        die("Function call failed with SQLSTATE " . $ei[0] . ", message " . $ei[2] . "\n");

        // Shortcut way:
        // die("Function call failed with SQLSTATE " . $sth->errorCode());
}
?>

输出是:

Function call failed with SQLSTATE UE001, message ERROR:  error message

将第二个 $sth-&gt;execute() 到代码末尾的代码块替换为这个,以证明异常处理模式也可以正常工作:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
        $sth->execute();
} catch (PDOException $err) {
        $ei = $err->errorInfo;
        die("Function call failed with SQLSTATE " . $ei[0] . ", message " . $ei[2] . "\n");

        // Alternate version to just get code:
        //die("Function call failed with SQLSTATE " . $err->getCode() . "\n");
}

【讨论】:

  • @AndreiTchijov 答案已修改。
  • @AndreiTchijov 您是否有可能使用不支持用户定义的 RAISE 上的 SQLSTATE 的旧 PostgreSQL 版本?你的 PostgreSQL 版本是什么? (你真的应该总是在问题中提到这一点)。
  • @AndreiTchijov 否则,请展示一个完全独立的代码示例来演示该问题,因为它对我来说很好,如上面编辑的答案所示。指定 PHP 版本、Pg 版本和您所在的平台。
  • 好的,谜团已经解开(我是个白痴)。有'当其他人引发异常'NUM:%,细节:%',SQLSTATE,SQLERRM;'在引发异常的 SPROC 中,我遇到了问题。我唯一的借口 - 这是该死的大 SPROC。
  • 只是为了自学,你知道errorInfo[1]中的'7'是从哪里来的吗?
猜你喜欢
  • 1970-01-01
  • 2011-07-16
  • 2021-05-08
  • 2020-03-07
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
  • 2011-09-03
  • 1970-01-01
相关资源
最近更新 更多