Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I ensure I caught all errors from MySQLi::multi_query?

Tags:

php

mysql

mysqli

The docs for multi_query say:

Returns FALSE if the first statement failed. To retrieve subsequent errors from other statements you have to call mysqli_next_result() first.

The docs for next_result say:

Returns TRUE on success or FALSE on failure.

Finally, the example posted in the docs for multi_query use the return value from next_result to determine when there are no more queries; e.g. to stop looping:

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query  = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";

    /* execute multi query */
    if ($mysqli->multi_query($query)) {
        do {
            /* store first result set */
            if ($result = $mysqli->store_result()) {
                while ($row = $result->fetch_row()) {
                    printf("%s\n", $row[0]);
                }
                $result->free();
            }
            /* print divider */
            if ($mysqli->more_results()) {
                printf("-----------------\n");
            }
        } while ($mysqli->next_result()); // <-- HERE!
    }

    /* close connection */
    $mysqli->close();
    ?>

I don't know the number of queries provided, nor do I know anything about the SQL that I'm going to execute. I therefore can't just compare the number of queries against the number of returned results. Yet I want to display an error message to the user if, say, the third query was the broken query. But I don't seem to have a way to tell if next_result failed because there were no more queries to execute, or if it's because there was an error in the SQL syntax.

How can I check all the queries for errors?

like image 960
Billy ONeal Avatar asked Sep 12 '11 23:09

Billy ONeal


People also ask

How can I see mysqli errors?

Just simply add or die(mysqli_error($db)); at the end of your query, this will print the mysqli error.

What is the mysqli function to check if there any more results from a multi query?

To check if there are more results, use mysqli_more_results(). For queries which produce a result set, such as SELECT, SHOW, DESCRIBE or EXPLAIN , mysqli_use_result() or mysqli_store_result() can be used to retrieve the result set.

What is mysqli error?

PHP mysqli_error() function returns an string value representing the description of the error from the last MySQLi function call. If there are no errors this function returns an empty string.

Which mysqli function returns the last error code from the last connection error?

The error / mysqli_error() function returns the last error description for the most recent function call, if any.


2 Answers

Despite the code example in the docs, perhaps the better method would be something like this:

if ($mysqli->multi_query(...)) {
  do {
    // fetch results

    if (!$mysqli->more_results()) {
      break;
    }
    if (!$mysqli->next_result()) {
      // report error
      break;
    }
  } while (true);
}
like image 177
Bill Karwin Avatar answered Oct 31 '22 19:10

Bill Karwin


There is no way to caught all errors, check out the example you use (which is from here)

This example has only "select" statements in it, which is not common for multi-statement scripts.

If you will put "insert", "update", "delete" or at least "set" - it will work differently.

"multi_query" - Returns FALSE if the first statement failed. FIRST STATEMENT - this is all we can control. All subsequent statement are mystery. If it is not a "select" statement - it will give an error on "$mysqli->store_result();" and we never know was it successful or not.

BUT

If you will have your SQL script in "START TRANSACTION; ... commit;" wrapper, you can be sure - if something fails, everything fails. This is good, this is helping us to see if "all fails".

To do this, just add in the end of you "insert - update" script a little "select", if last statement returns data - all script completed successfully.

Use SQL like:

START TRANSACTION;    
  set @q=1;
  select "success" as response from dual;
commit;

The PHP function:

function last_of_multi_query ($mysqli, $query) {
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); //After that all mysql errors will be transferred into PHP exceptions.
    $mysqli->multi_query($query);               
    do { null; } while($mysqli->next_result());
    $result = $mysqli->store_result();
    if (!$result){
        throw new Exception('multi_query failed');
    }
    return $result;
}// end function
like image 23
Yevgeniy Afanasyev Avatar answered Oct 31 '22 19:10

Yevgeniy Afanasyev