插入或删除时,与PDO的DB2连接会抛出一般错误-7008

时间:2019-06-26 10:16:50

标签: php pdo odbc ibm-midrange db2-400

我们正在开发一个PHP应用程序,该应用程序同时使用DB2连接到PostgreSQL服务器和IBM i服务器。尽管与PGSQL的PDO连接可以正常工作,但与DB2的连接只能从表中获取。尝试插入或删除会导致以下错误:

SQLSTATE[HY000]: General error: -7008 (SQLExecute[4294960288] at /build/php7.0-ltLrbJ/php7.0-7.0.33/ext/pdo_odbc/odbc_stmt.c:260)

此错误在我们的开发和生产环境中均会发生。两台服务器都是Ubuntu(不同版本,但相差不大)。我正在使用PDO的ODBC驱动程序。

我们尝试用不同的用户连接到其他IBM i服务器,但是仍然出现完全相同的问题。可以选择,但不能插入。谷歌搜索错误代码不会产生任何有用的结果,并且您可以看到错误消息本身就没有任何帮助。 SQLExecute中的代码尤其不会出现在任何地方,甚至不会出现任何结果(IBM页面有结果,但实际上是不同的错误代码)。

代码非常简单,但也许那里存在一些明显而明显的错误。

测试脚本:

include("DB2.php");
$oDAO = new DAO();
$res = $oDAO->ejecuta("INSERT INTO <Library>.<File> VALUES (1,0,1)");

DAO:

class DAO{
    var $link;

    public function __construct(){
        // función constructora, inicia la conexión

        $this->link = new PDO("odbc:DRIVER={IBM i Access ODBC Driver};SYSTEM=<System>;PROTOCOL=TCPIP",
                            '<user>', '<pass>');
        $this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    }

    private function begin()    { $this->link->beginTransaction(); }
    private function rollback() { $this->link->rollBack(); }
    private function commit()   { $this->link->commit(); }

    public function ejecuta($query){
        try{
            $this->begin();
            $oResult = $this->link->query($query);
            if($oResult){
                $bResult = true;
                $this->commit();
            }else{
                $bResult = false;
                $this->rollback();
            }
        }
        catch (Exception $e){
            echo $e->getMessage();
            $bResult = false;
            $this->rollback();
        }
        return $bResult;
    }
}

坦率地说,我们没有选择权,我已经浪费了两个星期。我们只需要插入和删除记录。因此,欢迎您提供任何帮助。

1 个答案:

答案 0 :(得分:2)

您描述的症状与在承诺控制下尝试修改数据库一致,但未启用日记功能。

有三种常见的处理方法:

  1. 打开日记功能。这是非常极端的,因为管理数据库的人将必须执行此操作,并且如果关闭了日记功能,则很可能他们根本不知道如何处理日记,或者不想这么做。但这是对i的Db2进行完全承诺控制的唯一实用方法。

  2. 启用自动提交连接。这将向通过此连接执行的任何修改数据库的SQL语句添加隐式提交。以我的经验,这是处理这种情况的最常见,最方便的方法。

  3. WITH NC添加到每个相关的SQL语句中。原则上,这使您可以按语句来控制是否暂停承诺控制。在实践中,如果首先考虑这样做,则可能没有启用日记功能,因此,您将必须对每个修改数据库的SQL语句执行此操作。这就是为什么大多数人倾向于选择选项2的原因。