2012-07-15 7 views
6

So che questa domanda è stato chiesto molte volte, ma ho letto le risposte a molte delle domande e ancora non riesco a capire il motivo per cui sto ricevendo questo errore:.PDO "eccezione non rilevata 'PDOException' .. Impossibile eseguire query mentre sono attive altre query non bufferizzate. Considerare l'utilizzo di PDOStatement :: fetchAll() “

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2014 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.'

La prima cosa strana è che non ottengo un errore sul mio localhost (wampserver), ma lo prendo sul mio server web. La versione php sul mio localhost è la 5.3.10, e sul mio web server è 5.3.13.

Ho letto che l'origine di questo errore sta creando una query quando i dati sono rimasti nel buffer da una query precedente. Questo non è il mio caso: ho echeggiato tutti i dati e so per certo che ogni riga restituita in una query è stata recuperata.

Detto questo, ho trovato che cambiare una delle mie domande al fetchAll invece di fetch risolve il problema, ma rende semplicemente non dato perché io so che tutte le righe restituite vengono letti. Quando ho usato fetchAll per la query (è stato creato in un ciclo), ho stampato l'array ogni ciclo e solo un elemento era nell'array per ogni query nel ciclo.

Un altro pezzo di informazione. Non è la query che ho modificato in fetchAll (che rende l'errore andare via) che genera l'errore PDO, c'è un'altra query più avanti nel mio file php che genera l'errore. Il mio file è fondamentalmente come questo:

... code ... 

query 1 

... code ... 

loop 
query 2 
end loop 

... code ... 

query 3 

Se io commento interrogazione 3, non ci sono errori. Se commento, o passare a fetchAll, query 2, non vi è alcun errore. la query 1 non ha alcun effetto.

Vorrei anche aggiungere che ho provato ad aggiungere LIMIT 1 a tutte delle query nella pagina (allo stesso tempo), e l'errore è ancora lì. Penso che questo dimostri che non ci sono dati non letti nel buffer, giusto?

Sono davvero confuso, quindi gradirei il vostro consiglio. Prima che qualcuno si chiede, non posso pubblicare il codice completo per questo, ma qui è una versione semplificata del mio codice:

$stmt = $this->db->prepare('SELECT ... :par LIMIT 1'); 
makeQuery($stmt, array(':par' => $var)); 
$row = $stmt->fetch(PDO::FETCH_ASSOC); 


$stmt = $this->db->prepare('SELECT ... :par LIMIT 1'); 

for loop 
    makeQuery($stmt, array(':par' => $var)); 
    $row2 = $stmt->fetch(PDO::FETCH_ASSOC); 
    ... [use row2] ... 
end for loop 


$stmt = $this->db->prepare('SELECT ... :par LIMIT 1'); 
makeQuery($stmt, array(':par' => $var)); 
$row3 = $stmt->fetch(PDO::FETCH_ASSOC); 

Ecco makeQuery().

/************************************************************************************************************** 
* Function: makeQuery                       * 
* Desc: Makes a PDO query.                     * 
* Pre conditions: The statement/query and an array of named parameters (may be empty) must be passed.   * 
* Post conditions: The PDO query is executed. Exceptions are caught, displayed, and page execution stopped. * 
**************************************************************************************************************/ 
function makeQuery($stmt, $array, $errMsg = '') 
{ 
    try 
    { 
     $stmt->execute($array); 
    } 
    catch (PDOException $e) 
    { 
     print $errMsg != ''?$errMsg:"Error!: " . $e->getMessage() . "<br/>"; 
     die(); 
    } 
} 

Grazie per il vostro aiuto!

EDIT: Ho anche provato a fare quanto segue dopo interrogazione 2 (dal momento che sembra essere l'origine del problema:

$row2 = $stmt->fetch(PDO::FETCH_ASSOC); var_dump($row2); 

L'uscita era:

bool(false) 

Avete mi sono imbattuto in un Errore PDO

risposta

1

è necessario recuperare fino a quando un tentativo di recupero riga non riesce. So che si può avere solo una riga nel set di risultati e pensare che un recupero è sufficiente, ma non è così.

probabilmente hai altre istruzioni in cui non hai "recuperato completamente fino a quando un recupero non è riuscito".Sì, vedo che si recupera fino a quando il recupero non è riuscito per uno delle dichiarazioni.

anche, vedi closecursor()

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

o

$sql = "select * from test.a limit 1"; 
$stmt = $dbh->prepare($sql); 
$stmt->execute(array()); 
list($row) = $stmt->fetchAll(); //tricky 
+0

Solo per assicurati di aver capito - anche se è stata restituita una sola riga, e so che, per un dato motivo, devo recuperare più di una volta? Sta usando il closecursor() preferibile a farlo? Grazie. – Nate

+0

questo è corretto. e sì, closecursor() è preferito – goat

+0

Grazie per il vostro aiuto .. Quindi, per essere sicuro di averlo capito, chiamate closecursor() dopo ogni chiamata a execute()? – Nate

2

Dopo aver lottato con questo problema per giorni, ho finalmente scoperto che questo ha funzionato per me:

$db = new PDO ($cnstring, $user, $pwd); 
$db->setAttribute (PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);