When running multiple queries one after another especially when stored procedures are involved one must release all result sets and fetch all rows in each result set for a stored procedure before moving onto the next query. This is important because a stored procedure returns an extra (empty) result set as a result of having called the procedure itself.
In my case calling PDOStatement :: closeCursor() did not work (on php-5.1.3-rc2) and I was presented with the following error message: "SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query" upon trying to PDO :: prepare() my second query. So I used the following drop in replacement within one of my classes which fixed the issue.
<?php
/**
* @param PDOStatement $oStm
*/
public static function closeCursor($oStm) {
do $oStm->fetchAll();
while ($oStm->nextRowSet());
}
?>
PDOStatement->closeCursor
(PHP 5 >= 5.1.0, PECL pdo >= 0.9.0)
PDOStatement->closeCursor — Ferme le curseur, permettant à la requête d'être de nouveau exécutée
Description
PDOStatement::closeCursor() libère la connexion du serveur, permettant ainsi à d'autres requêtes SQL d'être exécutées, mais quitte la requête, permettant ainsi qu'elle soit de nouveau exécutée.
Cette méthode est utile pour les drivers de base de données qui ne supportent pas l'exécution d'objet PDOStatement lorsqu'un objet PDOStatement exécuté précédemment a encore des lignes non récupérées. Si votre driver de base de données souffre de cette limitation, le problème se manifestera de lui-même dans une erreur en dehors de la séquence.
PDOStatement::closeCursor() est implémenté soit en tant que méthode optionnelle spécifique au pilote, avec un maximum d'efficacité, ou en tant que solution générique si aucune fonction spécifique au pilote n'est installée. Sémantiquement, la fonction générique PDO revient à écrire le code suivant dans votre script PHP :
<?php
do {
while ($stmt->fetch())
;
if (!$stmt->nextRowset())
break;
} while (true);
?>
Valeurs de retour
Cette fonction retourne TRUE en cas de succès, FALSE en cas d'échec.
Exemples
Exemple #1 Exemple avec PDOStatement::closeCursor()
Dans l'exemple suivant, l'objet PDOStatement $stmt retourne de multiples lignes, mais l'application récupère uniquement la première ligne, laissant l'objet PDOStatement dans l'état où il lui reste des lignes non récupérées. Pour vous assurez que l'application fonctionnera avec tous les drivers de base de données, l'auteur insère un appel à la fonction PDOStatement::closeCursor() sur $stmt avant l'exécution d'objet PDOStatement $otherStmt.
<?php
/* Création d'un objet PDOStatement */
$stmt = $dbh->prepare('SELECT foo FROM bar');
/* Création d'un second objet PDOStatement */
$otherStmt = $dbh->prepare('SELECT foobaz FROM foobar');
/* Exécute la première requête */
$stmt->execute();
/* Récupération de la première ligne uniquement depuis le résultat */
$stmt->fetch();
/* L'appel suivant à closeCursor() peut être requis par quelques drivers */
$stmt->closeCursor();
/* Maintenant, nous pouvons exécuter la deuxième requête */
$otherStmt->execute();
?>
PDOStatement->closeCursor
29-Apr-2006 08:23
