【发布时间】:2011-01-22 00:34:36
【问题描述】:
我正在使用 mysqli 提交语句插入大量记录,使用来自http://www.php.net/manual/en/mysqli.commit.php#88857 的这段代码。然后我使用以下命令检查受影响的行: $mysqli->affected_rows 但即使所有记录都已插入,我得到的受影响行数为零。
如何检查提交失败的时间并检索错误? 谢谢
【问题讨论】:
我正在使用 mysqli 提交语句插入大量记录,使用来自http://www.php.net/manual/en/mysqli.commit.php#88857 的这段代码。然后我使用以下命令检查受影响的行: $mysqli->affected_rows 但即使所有记录都已插入,我得到的受影响行数为零。
如何检查提交失败的时间并检索错误? 谢谢
【问题讨论】:
你可以这样做:
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());
}
【讨论】:
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 获取相关信息。
【讨论】: