首页 > 解决方案 > 插入或删除时与 PDO 的 DB2 连接引发一般错误 -7008

问题描述

我们正在开发一个 PHP 应用程序,它同时连接到 PostgreSQL 服务器和带有 DB2的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)");

道:

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;
    }
}

坦率地说,我们别无选择,我已经为此浪费了两周时间。我们只需要插入和删除记录。因此,欢迎任何帮助。

标签: phppdoodbcibm-midrangedb2-400

解决方案


您描述的症状与尝试在提交控制下修改数据库但未启用日志记录一致。

有三种常见的方法来处理这个问题:

  1. 打开日记功能。这是相当极端的,因为管理数据库的人必须这样做,如果他们关闭了日志功能,他们很可能要么真的不知道如何处理日志,要么不想这样做。但这是对 Db2 for i 进行完全承诺控制的唯一实用方法。

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

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


推荐阅读