Mysql
 sql >> база данни >  >> RDS >> Mysql

PDO „Неуловено изключение „PDOException“ .. Не може да се изпълняват заявки, докато други небуферирани заявки са активни. Помислете за използването на PDOStatement::fetchAll().”

Трябва да извличате, докато опитът за извличане на ред не успее. Знам, че може да имате само един ред в набора от резултати и да смятате, че едно извличане е достатъчно, но не е (когато използвате небуферирани заявки). PDO не знае колко реда има, докато не стигне до края, където се опитва да извлече следващия ред, но не успява.

Вероятно имате и други твърдения, при които не сте извадили напълно, докато извличането не е било неуспешно. Да, виждам, че извличате, докато извличането е неуспешно за един от твърденията, но това не означава, че сте го направили за всички тях.

За да изясним - Когато изпълнявате заявка чрез execute(), създавате набор от резултати, който трябва да бъде извлечен от db в php. PDO може да обработва само 1 от тези „набор от резултати в процес на извличане“ наведнъж (на връзка). Трябва да извлечете напълно резултатния набор, чак до края му, преди да можете да започнете да извличате различен набор от резултати от различно извикване на execute().

Когато "извикате fetch(), докато fetch() не успее", фактът, че сте достигнали края на резултатите, се отбелязва вътрешно от PDO, когато последното извикване на fetch() се провали поради липса на повече резултати. След това PDO се уверява, че резултатите са напълно извлечени и може да почисти всякакви вътрешни ресурси между php и db, които са били установени за този набор от резултати, което ви позволява да правите/извличате други заявки.

Има и други начини да направите PDO „извикване на fetch(), докато fetch() не успее“.

  1. Просто използвайте fetchAll(), който просто извлича всички редове и така ще достигне края на набора от резултати.
  2. или просто извикайте closeCursor()

*ако погледнете източника за closeCursor(), реализацията по подразбиране буквално просто извлича редовете и ги изхвърля, докато стигне до края. Очевидно е написано в c, но повече или по-малко прави това:

function closeCursor() {
    while ($row = $stmt->fetch()) {}
    $this->stmtFullyFetched = true;
}

Някои db драйвери може да имат по-ефективна реализация, която не изисква от тях да извличат много редове, за които никой не се интересува, но това е начинът по подразбиране, по който PDO го прави. Както и да е...

Обикновено нямате тези проблеми, когато използвате буферирани заявки. Причината е, че с буферирани заявки, веднага след като ги изпълните, PDO автоматично ще извлече напълно резултатите от db в php паметта, така че автоматично извършва частта "извикване fetch(), докато извличане() не успее" вместо вас. Когато по-късно сами извикате fetch() или fetchAll(), това извлича резултати от php памет, а не от db. Така че по принцип, наборът от резултати се извлича незабавно напълно, когато се използват буферирани заявки, така че няма възможност да имате повече от 1 „набор от резултати в процес на извличане“ по едно и също време (тъй като php е еднонишков, така че няма шанс за 2 заявки работи едновременно).

Като се има предвид това:

$sql = "select * from test.a limit 1";
$stmt = $dbh->prepare($sql);
$stmt->execute(array());

Начини за пълно извличане на набора от резултати (ако приемем, че искате само първия ред):

$row = $stmt->fetch();
$stmt->closeCursor();

или

list($row) = $stmt->fetchAll(); //tricky

или

$row = $stmt->fetch();
while ($stmt->fetch()) {}


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Премахване на дублиращи се редове в MySQL

  2. Как мога да изчистя екрана в MySQL конзолата?

  3. Може ли Laravel да се справи с приложения с голям трафик?

  4. MySQL задава текуща дата в поле DATETIME при вмъкване

  5. Каква е разликата между mysql drop partition и truncate дял