I am inserting a lot of records using mysqli commit statement, using this code from http://www.php.net/manual/en/mysqli.commit.php#88857. I then check affected rows using: $mysqli->affected_rows but even though all records have been inserted, I get zero affected rows.
How can I check when commit failed and retrieve the error? Thank you
Just simply add or die(mysqli_error($db)); at the end of your query, this will print the mysqli error.
If you want to display errors like "Access denied...", when mysql_error() returns "" and mysql_errno() returns 0, use $php_errormsg. This Warning will be stored there. You need to have track_errors set to true in your php.
The connect_error / mysqli_connect_error() function returns the error description from the last connection error, if any.
The mysqli_error() function / mysqli::$error returns the last error description for the most recent function call, if any.
You could do something like this:
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);
}
When a query goes wrong, it will add the error to the $errors array, so you will know what went wrong. You could also add keys with identifiers for the queries, so you know which query went wrong.
For better handling, you could write a UnitOfWork class for this:
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
}
}
and you could use it like
$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
will return the number of rows affected by the last MySQL operation.
If you are doing something like this (pseudo-code) :
$db->query("insert ...");
$db->query("insert ...");
$db->query("insert ...");
$db->commit();
$num = $db->affected_rows();
You will not get the number of inserted rows : the commit
instruction is the last executed one, and it doesn't "affect" any row.
If you want to know whether mysqli::commit
succedeed or not, you should check it's return value (quoting) :
Returns
TRUE
on success orFALSE
on failure.
If it returned true
, then all your previous inserts, since the beginning of the current transaction, will have been commited.
And if an error occured, you can use mysqli::errno
and/or mysqli::error
to get informations about it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With