【问题标题】:PHP: How can I check for errors during a mysqli commit?PHP:如何在 mysqli 提交期间检查错误?
【发布时间】:2011-01-22 00:34:36
【问题描述】:

我正在使用 mysqli 提交语句插入大量记录,使用来自http://www.php.net/manual/en/mysqli.commit.php#88857 的这段代码。然后我使用以下命令检查受影响的行: $mysqli->affected_rows 但即使所有记录都已插入,我得到的受影响行数为零。

如何检查提交失败的时间并检索错误? 谢谢

【问题讨论】:

    标签: php mysqli commit


    【解决方案1】:

    你可以这样做:

    mysqli_autocommit($dbconn, FALSE);
    
    $errors = array();
    
    if (!$mysqli->query(/* some SQL query */)) {
        $errors[] = $mysqli->error;
    }
    // ... more queries like the above
    if(count($errors) === 0) {
        $mysqli->commit()
    } else {
        $mysqli->rollback();
        print_r($errors);
    }
    

    当查询出错时,它会将错误添加到 $errors 数组中,这样您就知道出了什么问题。您还可以为查询添加带有标识符的键,这样您就知道哪个查询出错了。

    为了更好地处理,您可以为此编写一个UnitOfWork 类:

    class UnitOfWork
    {
        protected $_db;
        protected $_errors;
        protected $_queries;
        public function __construct($db) {
            $this->_db = $db;
            $this->_errors = array();
            $this->_queries = array();
        }
        public function addQuery($id, $sql) {
            $this->_queries[$id] = $sql;
            return $this;
        }
        public function getErrors() {
            return $this->_errors;
        }    
        public function try() {
            $this->_db->autocommit($this->_db, FALSE);
            foreach($this->_queries as $id => $query) {
                if ($this->_db->query($query) === FALSE) {
                    $this->_errors[$id] = $this->_db->error;
                }
            }
            $hasErrors = count($this->_errors);
            ($hasErrors) ? $this->_db->rollback() : $this->_db->commit();
            $this->_db->autocommit($this->_db, TRUE);
            return !$hasErrors; // return true on success
        }
    }
    

    你可以像这样使用它

    $unit = new UnitOfWork($mysqli);
    $unit->addQuery('foo', 'SELECT foo FROM somewhere')
         ->addQuery('bar', 'SELECT bar FROM somewhereElse')
         ->addQuery('baz', 'SELECT baz WITH brokenQuery');
    
    if($unit->try() === FALSE) {
        print_r($unit->getErrors());
    }
    

    【讨论】:

      【解决方案2】:

      mysqli::affected_rows 将返回最后一次 MySQL 操作影响的行数。

      如果你正在做这样的事情(伪代码):

      $db->query("insert ...");
      $db->query("insert ...");
      $db->query("insert ...");
      $db->commit();
      $num = $db->affected_rows();
      

      您不会得到插入的行数:commit 指令是最后执行的指令,它不会“影响”任何行。


      如果你想知道mysqli::commit 是否成功,你应该检查它的返回值(quoting)

      成功返回 TRUE 或返回 FALSE 失败。

      如果它返回true,那么自当前事务开始以来,您之前的所有插入都将被提交。


      如果发生错误,您可以使用mysqli::errno 和/或mysqli::error 获取相关信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-19
        • 2015-04-29
        • 1970-01-01
        • 2017-04-27
        相关资源
        最近更新 更多