sql >> Database >  >> RDS >> Mysql

PDO “Uncaught exception 'PDOException' .. Kan geen query's uitvoeren terwijl andere niet-gebufferde query's actief zijn. Overweeg het gebruik van PDOStatement::fetchAll().”

U moet ophalen totdat een poging om een ​​rij op te halen mislukt. Ik weet dat je misschien maar één rij in de resultatenset hebt en denk dat één ophaalactie voldoende is, maar dat is het niet (wanneer je niet-gebufferde zoekopdrachten gebruikt). PDO weet niet hoeveel rijen er zijn totdat het het einde bereikt, waar het probeert de volgende rij op te halen, maar het mislukt.

U hebt waarschijnlijk andere instructies waarbij u niet volledig "ophaalt totdat een ophaalactie is mislukt". Ja, ik zie dat je ophaalt totdat het ophalen één failed mislukte van de uitspraken, maar dat betekent niet dat je het voor allemaal hebt gedaan.

Ter verduidelijking:wanneer u een query uitvoert via execute(), maakt u een resultatenset die van de db in php moet worden opgehaald. PDO kan slechts 1 van deze "resultatenset wordt opgehaald" tegelijk (per verbinding) aan. U moet de resultatenset volledig ophalen, helemaal tot het einde ervan, voordat u een andere resultatenset kunt ophalen van een andere aanroep om uit te voeren().

Wanneer u "fetch() aanroept totdat een fetch() mislukt", wordt het feit dat u het einde van de resultaten hebt bereikt intern opgemerkt door PDO wanneer die laatste aanroep van fetch() mislukt omdat er geen resultaten meer zijn. PDO is er dan van overtuigd dat de resultaten volledig zijn opgehaald en kan alle interne bronnen tussen php en de db opschonen die voor die resultatenset zijn ingesteld, zodat u andere query's kunt maken/ophalen.

Er zijn andere manieren om een ​​PDO te maken "call fetch() totdat een fetch() mislukt".

  1. Gebruik gewoon fetchAll(), dat eenvoudig alle rijen ophaalt, zodat het het einde van de resultatenset bereikt.
  2. of bel gewoon closeCursor()

*als je naar de bron voor closeCursor() kijkt, haalt de standaardimplementatie letterlijk de rijen op en gooit ze weg totdat het einde is bereikt. Het is duidelijk in c geschreven, maar het doet min of meer dit:

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

Sommige db-stuurprogramma's hebben misschien een efficiëntere implementatie die niet vereist dat ze veel rijen ophalen waar niemand om geeft, maar dat is de standaardmanier waarop PDO het doet. Hoe dan ook...

Normaal gesproken heb je deze problemen niet als je gebufferde queries gebruikt. De reden is dat met gebufferde zoekopdrachten, direct nadat je ze hebt uitgevoerd, PDO de db-resultaten automatisch volledig in het php-geheugen zal ophalen, dus het doet het gedeelte "call fetch() totdat een fetch() faalt" automatisch voor je. Als je later zelf fetch() of fetchAll() aanroept, haalt het de resultaten op uit het php-geheugen, niet uit de db. Dus eigenlijk wordt de resultatenset onmiddellijk volledig opgehaald bij gebruik van gebufferde zoekopdrachten, dus er is geen mogelijkheid om meer dan 1 "resultaatset die wordt opgehaald" tegelijkertijd te hebben (omdat php single-threaded is, dus geen kans op 2 zoekopdrachten tegelijkertijd draaien).

Gezien dit:

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

Manieren om de resultatenset volledig op te halen (ervan uitgaande dat u alleen de eerste rij wilt):

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

of

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

of

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


  1. hoe krijg ik mysql-resultaten van de datum van vandaag?

  2. Succesvolle SQL-injectie ondanks PHP Magic Quotes

  3. Wat is de beste manier om meerdere rijen in een mysql-database in te voegen met behulp van php?

  4. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:onbekende kolom 'Smith' in 'where-clausule'