Я сталкиваюсь с ошибкой, использующей инструкцию PDO, чтобы сделать несколько выборок.
Я создаю SQL-запрос с множеством SELECT и независимо от количества выражений SELECT, последний набор строк отбрасывается.
Вот усеченный пример того, что происходит
$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());
Выполнение вышеизложенного, 1-3 успешно извлекаются в виде наборов строк, а 4 – нет.
Я не могу объяснить, почему это так. Выполнение любых последующих запросов с одним и тем же объектом PDO приводит к ошибке:
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.
Вышеприведенные do ... while ...
рутина основывалась на том, что можно найти в документации PHP на функции nextRowset()
адресу http://us1.php.net/manual/en/pdostatement.nextrowset.php
Вызов $statement->closeCursor()
в конце не работает
Подпрограммы, которые я использую, значительно сложнее, но я могу подтвердить, что sql ведет себя так, как ожидалось (подключая его непосредственно в MySQL с помощью PHPMyAdmin и запуская его с помощью mysqli->multi_query()
, оба из которых возвращают ожидаемые результаты)
Я нашел кого-то, у кого была аналогичная проблема, и выпустил билет с ошибкой PHP, который, по-видимому, был отмечен как исправленный: https://bugs.php.net/bug.php?id=61207&edit=1
Может ли кто-нибудь объяснить мне, что вызывает сброс последнего набора строк? Благодаря!
Версии: PHP 5.4.12 , MySQL 5.6.12
Изменить 1: я попытался использовать MYSQL_ATTR_USE_BUFFERED_QUERY, изменив код на …
$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());
Это не решило проблему
Я думаю, что вы слишком усложняете свой цикл do / while.
Попробуйте простой цикл while:
$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(); }
Это продолжит цикл, тогда как rowset не будет иметь ложное значение, которое должно работать точно так, как вы ожидаете.
Чтобы избежать этого PDOException
просто используйте columnCount
:
while ($statment->columnCount()) { $rowset = $statment->fetchAll(PDO::FETCH_ASSOC); $statment->nextRowset(); }