sql >> Databasteknik >  >> RDS >> Mysql

PDO “Ofångat undantag 'PDOException' .. Kan inte köra frågor medan andra obuffrade frågor är aktiva. Överväg att använda PDOStatement::fetchAll()."

Du måste hämta tills ett radhämtningsförsök misslyckas. Jag vet att du kanske bara har en rad i resultatuppsättningen och tror att en hämtning räcker, men det är det inte (när du använder obuffrade frågor). PDO vet inte hur många rader det finns förrän den når slutet, där den försöker hämta nästa rad, men det misslyckas.

Du har förmodligen andra påståenden där du inte helt "hämtade förrän en hämtning misslyckades". Ja, jag ser att du hämtar tills hämtningen misslyckades för en av påståendena, men det betyder inte att du gjorde det för dem alla.

För att förtydliga -När du kör en fråga via execute(), skapar du en resultatuppsättning som måste hämtas från db till php. PDO kan endast hantera 1 av dessa "resultatset pågår att hämtas" åt gången (per anslutning). Du måste hämta resultatuppsättningen helt, ända till slutet av den, innan du kan börja hämta en annan resultatuppsättning från ett annat anrop till execute().

När du "anropar fetch() tills en fetch() misslyckas", noteras det faktum att du nådde slutet av resultaten internt av PDO när det sista anropet till fetch() misslyckas på grund av att det inte finns några fler resultat. PDO är då nöjd med att resultaten är helt hämtade, och den kan rensa upp alla interna resurser mellan php och db som etablerades för den resultatuppsättningen, så att du kan göra/hämta andra frågor.

Det finns andra sätt att göra PDO "anrop fetch() tills en fetch() misslyckas".

  1. Använd bara fetchAll(), som helt enkelt hämtar alla rader, så kommer den att träffa slutet av resultatuppsättningen.
  2. eller bara ring closeCursor()

*om du tittar på källan för closeCursor(), hämtar standardimplementeringen bokstavligen bara raderna och kasserar dem tills den når slutet. Det är så klart skrivet i c, men det gör mer eller mindre så här:

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

Vissa db-drivrutiner kan ha en mer effektiv implementering som inte kräver att de hämtar massor av rader som ingen bryr sig om, men det är standardsättet för PDO. Hur som helst...

Normalt har du inte dessa problem när du använder buffrade frågor. Anledningen är att med buffrade frågor, direkt efter att du har kört dem, kommer PDO automatiskt att hämta db-resultaten helt till php-minnet, så det gör "call fetch() tills en fetch() misslyckas"-delen för dig, automatiskt. När du senare själv anropar fetch() eller fetchAll() hämtar det resultat från php-minnet, inte från db. Så i grund och botten hämtas resultatuppsättningen omedelbart helt när du använder buffrade frågor, så det finns ingen möjlighet att ha mer än 1 "resultatuppsättning som pågår att hämtas" samtidigt (eftersom php är entrådad, så ingen chans till 2 frågor körs samtidigt).

Med tanke på detta:

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

Sätt att hämta resultatuppsättningen helt (förutsatt att du bara vill ha den första raden):

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

eller

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

eller

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


  1. Konstig MySQL Python mod_wsgi Kan inte ansluta till MySQL-servern på "localhost" (49) problem

  2. SELECT fungerar inte i node.js

  3. Hur man hittar minimivärden i kolumner

  4. Sanering och validering av formuläret php