PDO :: query () сталкивается с & quot; Невозможно выполнить запросы, пока другие небуферизованные запросы активны. & Quot;

Возможно, у некоторых других есть такая же проблема, как у меня.
Я перебил ошибку:

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.

на PDO. Как упоминалось во многих потоках, ошибка может быть как минимум одной из следующих проблем:

  1. Курсор запроса не был закрыт с closeCursor() как упомянуто здесь; Причины ошибки MySQL 2014. Невозможно выполнить запросы, когда другие небуферизованные запросы активны.
  2. Есть более двух запросов с одним утверждением, как упомянуто здесь: PDO не может выполнять запросы, когда другие небуферизованные запросы активны
  3. Ошибка в mysql-драйвере, как упомянуто здесь: Что является причиной ошибки PDO Не удается выполнить запросы, когда другие небуферизованные запросы активны?

В моем случае все вышеперечисленное не помогло, и потребовалось некоторое время, чтобы я решил проблему. это был мой код (псевдокод):

$stmt->startTransaction();
$stmt = db::getInstance()->prepare("CALL phones(:phone)");
$stmt->prepare('SELECT * FROM database');
$stmt->execute();
$aData = $stmt->fetchAll();
$stmt->closeCursor();

$stmt->query("USE sometable;");

После того как я изменил его на:

$stmt->startTransaction();
$stmt = db::getInstance()->prepare("CALL phones(:phone)");
$stmt->prepare('SELECT * FROM database');
$stmt->execute();
$aData = $stmt->fetchAll();
$stmt->closeCursor();

$stmt->exec("USE sometable;");

Это сработало для моего. В чем разница между запросом и exec?

PDO::exec() - "Execute an SQL statement and return the number of affected rows"PDO::query() - "Executes an SQL statement, returning a result set as a PDOStatement object"

Почему в этом случае PDO :: query () не работает? Курсор закрывается при вызове.

4

Решение

Пока это мог Можно предположить, что вы столкнулись с ошибкой драйвера mysql, и мы не можем быть в этом уверены, потому что вы не предоставили нам эту информацию (какую версию PHP вы используете? mysqlnd => проверить с php -i | grep mysqlnd? Как выглядит остальная часть вашего кода?).
Есть много других возможных объяснений вашей проблемы. Я подозреваю, что проблема заключается в том, что вы не можете закрыть все курсоры и / или получить все результаты, потому что $stmt используется повторно сильно:

Цитируется прямо из PDO::query страница справочника:

Если вы не получите все данные в наборе результатов, прежде чем отправлять свой следующий вызов PDO::query()Ваш звонок может не состояться. Вызов PDOStatement::closeCursor() освободить ресурсы базы данных, связанные с PDOStatement возражать, прежде чем сделать следующий вызов PDO::query(),

Ты звонишь closeCursor на $stmtэто правда, но вы не закрыты все курсоры, которые были созданы вами:

//<-- what is $stmt here?
$stmt->startTransaction();
//no matter, you've reassigned it a PDOStatement instance
$stmt = db::getInstance()->prepare("CALL phones(:phone)");
//Huh? You're preparing yet another query on an instance of PDOStatement?
$stmt->prepare('SELECT * FROM database');
//you're executing this one, though
$stmt->execute();
//and fetching all data
$aData = $stmt->fetchAll();
//and closing this last statement
$stmt->closeCursor();

Но как насчет первого заявления, которое вы назначили $stmt (вызов хранимой процедуры)? Этот курсор нигде не закрыт

Теперь для основной разницы между PDO::query а также PDO::exec, Опять цитируем руководство:

PDO::exec() не возвращает результаты из оператора SELECT.

В то время как:

PDO::query() выполняет оператор SQL в одном вызове функции, возвращая результирующий набор (если есть), возвращенный оператором, как PDOStatement объект.

3

Другие решения

Я тоже сталкивался с этой проблемой. Это может быть ошибка. Если мы возьмем следующий код, вы увидите, как он выходит из строя, с сообщением «Общая ошибка: 2014 г. Невозможно выполнить запросы, пока активны другие небуферизованные запросы. Попробуйте использовать PDOStatement :: fetchAll (). ‘

$pdo = new \PDO("mysql:host=localhost", "root", "");
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);

$pdo->query("USE test");

Если вы измените $pdo->query("USE test"); в $pdo->exec("USE test"); это будет работать. Если вы измените $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); в $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true); это тоже будет работать. Я пока не смог найти правильного решения.

1

По вопросам рекламы [email protected]