I'm experiencing what appears to be a bug using a PDO statement to make multiple selects.
I'm building a SQL query that has many SELECTs, and regardless of how many SELECT statements it makes, the last rowset is dropped.
Here's a truncated example of whats happening
$pdo = /* connection stuff here */
$sql = "select 1; select 2; select 3; select 4;";
$statement = $pdo->query($sql);
do {
$rowset = $statement->fetchAll();
if($rowset) {
// Do stuff with $rowset
}
} while($statement->nextRowset());
Doing the above, 1-3 are successfully retrieved as rowsets, but 4 is not.
I cannot explain why that is the case. Making any subsequent queries with the same PDO object results in an error:
PDO::query(): SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active.
Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
The above do ... while ...
routine was based off of what can be found in PHP's documentation on the nextRowset()
function at http://us1.php.net/manual/en/pdostatement.nextrowset.php
Calling $statement->closeCursor()
at the end doesn't seem to work
The routines I'm using are significantly more complex, but I can confirm that the sql behaves as expected (by plugging it into MySQL directly using PHPMyAdmin and running it using mysqli->multi_query()
, both of which return the expected results)
I found someone who had a similar issue and issued a PHP bug ticket, which was apparently marked as fixed: https://bugs.php.net/bug.php?id=61207&edit=1
Can anyone please explain to me what is causing the last rowset to be dropped? Thanks!
Versions: PHP 5.4.12, MySQL 5.6.12
Edit 1: I attempted to use MYSQL_ATTR_USE_BUFFERED_QUERY by changing the code to...
$pdo = /* connection stuff here */
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); // added code
$sql = "select 1; select 2; select 3; select 4;";
$statement = $pdo->query($sql);
do {
$rowset = $statement->fetchAll();
if($rowset) {
// Do stuff with $rowset
}
} while($statement->nextRowset());
This didn't solve the problem
I think you are over complicating things with your do/while loop.
Try a simple while loop instead:
$pdo = /* connection stuff here */
$sql = "select 1; select 2; select 3; select 4;";
$statement = $pdo->query($sql);
while($rowset = $statement->fetchAll()){
//do stuff
$statement->nextRowset();
}
This will continue looping while rowset does not have a false value which should then work exactly as you expect.
To avoid that PDOException
just use columnCount
:
while ($statment->columnCount()) {
$rowset = $statment->fetchAll(PDO::FETCH_ASSOC);
$statment->nextRowset();
}
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