Этот вопрос без принятого ответа вызывает катастрофическую проблему с MySQL, которую я испытываю в MySQL версии 5.6.16 на Windows в измененной форме.
Проблема легко воспроизводится: я включаю ее здесь (скопированный из связанного с ним вопроса, но с изменениями, применимыми к моему коду):
$pdo = /* connection stuff here */ $sql = "call test();"; // call stored procedure - see below $statement = $connection->query($sql); do { $rowset = $statement->fetchAll(PDO::FETCH_ASSOC); if($rowset) { // Do stuff with $rowset } } while($statement->nextRowset());
Вот определение test
хранимой процедуры:
DELIMITER $$ DROP PROCEDURE IF EXISTS `test`$$ CREATE PROCEDURE `test`() BEGIN SELECT 1; SELECT 2; SELECT 3; SELECT 4; END$$ DELIMITER ;
Единственное различие между моим кодом и связанным с ним кодом заключается в том, что я упаковываю SQL-запрос в хранимую процедуру.
В моем случае оператор while
возвращает true
четыре раза, а не три раза (это должно быть всего три раза). После четвертого раза fetchAll(...)
SQLSTATE[HY000]: General error
ошибка.
К сожалению, эта проблема катастрофична. Другим способом с PDO нет итерации для следующих nextRowSet()
кроме использования функции nextRowSet()
. Поэтому я могу вернуться к предыдущей версии MySQL, чтобы обойти эту проблему.
Я нашел две ссылки, которые, похоже, указывают на эту проблему, перечисленную здесь: https://bugs.php.net/bug.php?id=67130 и http://permalink.gmane.org/gmane.comp.php.devel / 81518
Я был бы признателен за подтверждение, что это, действительно, ошибка с версией MySQL 5.6.16 в Windows. Более того, я был бы признателен за обход. Благодарю.
У меня была такая же проблема с PDO :: nextRowset (), поскольку она возвращает true, даже если нет доступных наборов строк, поэтому при вызове fetchAll () возникает исключение HY000. (проверено на PHP 5.5.12 Windows, Mysql 5.5.17 Linux)
Обходной путь для этой проблемы заключается в проверке количества столбцов с методом PDO :: columnCount () перед выбором набора строк. Если он отличен от нуля, у вас есть допустимый набор строк, и вы можете вызвать PDO :: fetchAll ().
Даже если PDO :: nextRowset () сообщает true, columnCount () будет сообщать количество столбцов перед переходом к следующему набору строк.
Пример:
while ($objQuery->columnCount()) { $tab[] = $objQuery->fetchAll(\PDO::FETCH_ASSOC); $objQuery->nextRowset(); }
Если проблема вызвана множеством наборов результатов, то, возможно, лучшей работой было бы найти способы избежать множества наборов результатов в одном запросе.
Например, если ожидаемые результаты будут в том же формате (что, я думаю, они, вероятно, связаны с тем, что вы намерены использовать один и тот же код для решения всех проблем), вы можете использовать UNION для объединения четырех запросов.
SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4;
В противном случае вы можете выполнить отдельный запрос для каждого SELECT и передать результат в функцию для выполнения обработки.