sql >> Database teknologi >  >> RDS >> Mysql

PDO "Ufanget undtagelse 'PDOException' .. Kan ikke udføre forespørgsler, mens andre ubuffrede forespørgsler er aktive. Overvej at bruge PDOStatement::fetchAll()."

Du skal hente indtil et rækkehentningsforsøg mislykkes. Jeg ved, at du måske kun har én række i resultatsættet og tror, ​​at en hentning er nok, men det er det ikke (når du bruger ubuffrede forespørgsler). PDO ved ikke, hvor mange rækker der er, før den når slutningen, hvor den forsøger at hente den næste række, men det mislykkes.

Du har sikkert andre udsagn, hvor du ikke helt "hentede, før en hentning mislykkedes". Ja, jeg kan se, at du henter, indtil hentning mislykkedes for én af udsagnene, men det betyder ikke, at du gjorde det for dem alle.

For at præcisere -Når du udfører en forespørgsel via execute(), opretter du et resultatsæt, der skal hentes fra db'en til php. PDO kan kun håndtere 1 af disse "resultatsæt i gang med at blive hentet" ad gangen (pr. forbindelse). Du skal helt hente resultatsættet, helt til slutningen af ​​det, før du kan begynde at hente et andet resultatsæt fra et andet kald til execute().

Når du "kalder fetch() indtil en fetch() mislykkes", bliver det faktum, at du nåede slutningen af ​​resultaterne, internt noteret af PDO, når det sidste kald til fetch() mislykkes, fordi der ikke er flere resultater. PDO er så tilfreds med, at resultaterne er fuldt ud hentet, og den kan rydde op i de interne ressourcer mellem php og db, der blev etableret for det resultatsæt, så du kan lave/hente andre forespørgsler.

Der er andre måder at få PDO til at "kalde fetch() indtil en fetch() mislykkes".

  1. Bare brug fetchAll(), som ganske enkelt henter alle rækker, og så rammer den slutningen af ​​resultatsættet.
  2. eller bare kald closeCursor()

*hvis du ser på kilden til closeCursor(), henter standardimplementeringen bogstaveligt talt bare rækkerne og kasserer dem, indtil den når slutningen. Det er selvfølgelig skrevet i c, men det gør mere eller mindre dette:

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

Nogle db-drivere kan have en mere effektiv implementering, der ikke kræver, at de henter en masse rækker, som ingen bekymrer sig om, men det er standard måden PDO gør det på. I hvert fald...

Normalt har du ikke disse problemer, når du bruger bufferforespørgsler. Årsagen er, at med bufferforespørgsler, lige efter du har udført dem, vil PDO automatisk fuldt ud hente db-resultaterne ind i php-hukommelsen, så den udfører "kald fetch() indtil en fetch() fails"-delen automatisk for dig. Når du senere selv kalder fetch() eller fetchAll(), henter det resultater fra php-hukommelsen, ikke fra db. Så dybest set hentes resultatsættet med det samme, når du bruger bufferforespørgsler, så der er ingen mulighed for at have mere end 1 "resultatsæt i gang med at blive hentet" på samme tid (fordi php er enkelttrådet, så ingen chance for 2 forespørgsler kører på samme tid).

Givet dette:

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

Måder at hente resultatsættet fuldt ud (forudsat at du kun vil have den første række):

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

eller

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

eller

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


  1. Sådan gentager du tabelkolonneoverskriften på hver side

  2. Installation af Laravel på Ubuntu med Apache, MariaDB og PHP-support

  3. mySQL summen af ​​to værdier i 2 forskellige tabeller

  4. Formater mysql-forespørgselsresultatet til det ønskede format