MySQL Stored Procedure not throwing error if it contains a query that succeeds I am writing a simple MySQL Stored Procedure, and calling it from PHP using PDO.

This is just simple enough to illustrate the problem I'm having. 

This procedure test_procedure_2, does not throw any error.

CREATE PROCEDURE `test_procedure_1`()
BEGIN    
    select 'gary';

    CALL raise_error;
END


It returns the result set:

[0] =&gt; Array
    (
        [0] =&gt; Array
            (
                [gary] =&gt; gary
            )

    )


However... 

CREATE PROCEDURE `test_procedure_2`()
BEGIN            
    CALL raise_error;

    select 'gary';
END


...this procedure test_procedure_2, when called, will actually throw an PDOException with the message "SQLSTATE[42000]: Syntax error or access violation: 1305 PROCEDURE vjs_admin_dev.raise_error does not exist". And the select 'gary' query never gets executed. I like that.

Why is it that the first procedure did NOT throw an error when it clearly contained an error? I would like to come up with a stored procedure that, whenever there is an error anywhere in it, it will throw an error. Thanks for your help!

I'm using 


Ubuntu: 16.04, and
PHP: 7.0.15
mysql: Ver 14.14 Distrib 5.7.21, for Linux (x86_64) using  EditLine wrapper


EDIT:
I have tried this with mysqli, and with PDO, and I get the same results. Here are some simple code examples that show my issue: 


Mysqli Version: https://pastebin.com/rATMST4H
PDO version: https://pastebin.com/Wiq3yFmQ


The output of the Mysqli version is:

Running test_procedure_1
CREATE PROCEDURE `test_procedure_1`()BEGIN  select 'gary';  CALL raise_error;END
RESULTS:Array ( [gary] =&gt; gary ) 
----------
Running test_procedure_2
CREATE PROCEDURE `test_procedure_2`()BEGIN  CALL raise_error;   select 'gary';END
CALL failed: (1305) PROCEDURE vjs_admin_dev.raise_error does not exist
----------


The output of the PDO version is:

Running test_procedure_1
CREATE PROCEDURE `test_procedure_1`()BEGIN  select 'gary';  CALL raise_error;END
RESULTS:Array ( [gary] =&gt; gary [0] =&gt; gary ) 
----------
Running test_procedure_2
CREATE PROCEDURE `test_procedure_2`()BEGIN  CALL raise_error;   select 'gary';END
CALL failed: (42000) Array ( [0] =&gt; 42000 [1] =&gt; 1305 [2] =&gt; PROCEDURE vjs_admin_dev.raise_error does not exist ) 
----------
Wow, that's a relevant problem, because you can't identify an error in a procedure, an this passes hidden next to some valid result! I think your question should be more popular.

After many tries and tests I found a way to solve it. You'd expect to loop through the procedure result set, until no more results are available (the PHP Manual way). However, I found an alternate control flow to catch the errors after previous valid results:

&lt;?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
    $sql="CALL procedureWithErrors()";      
    $conn=new mysqli($host,$user,$pass,$db);

    /*The usual way (does not work)*/
    $conn-&gt;multi_query($sql);
    do{
        $result=$conn-&gt;store_result();      
        if($result){
            while($row=$result-&gt;fetch_assoc()){
                print_r($row);
            }
            $result-&gt;free();
        }                           
    }while($conn-&gt;more_results() &amp;&amp; $conn-&gt;next_result());

    /*This way works*/
    $conn-&gt;multi_query($sql);
    while(($result=$conn-&gt;store_result())!==FALSE){
        if($result){
            while($row=$result-&gt;fetch_assoc()){
                print_r($row);
            }
            $result-&gt;free();
        }                           
        $conn-&gt;next_result();
    }

    /*Just closing and error handling, not relevant code from here*/
    $conn-&gt;close();         

}catch(mysqli_sql_exception | Exception $e){    
    $error="Error #".$e-&gt;getCode()." ".$e-&gt;getMessage().PHP_EOL;    
    if(isset($conn) &amp;&amp; get_class($e)=="mysqli_sql_exception")
        $error.="SQLSTATE #".$conn-&gt;sqlstate." Statement: $sql".PHP_EOL;
    $error.=$e-&gt;getTraceAsString();
    echo(nl2br($error));    
}finally{
    if(isset($result) &amp;&amp; $result instanceof mysql_result) $result-&gt;free();          
    if(isset($conn) &amp;&amp; is_resource($conn) &amp;&amp; get_resource_type($conn)==='mysql link') $conn-&gt;close();
}
?&gt;


The problems seems to be that mysqli::more_results and mysql::next_result return FALSE if an error happens, so they can't distinguish between an error and the lack of further results.