Mysql
 sql >> Base de données >  >> RDS >> Mysql

Pourquoi mysqli génère-t-il une erreur de synchronisation des commandes ?

Le client MySQL ne vous permet pas d'exécuter une nouvelle requête lorsqu'il reste des lignes à extraire d'une requête en cours. Voir Commandes désynchronisées dans la documentation MySQL sur les erreurs courantes.

Vous pouvez utiliser mysqli_store_result() pour pré-extraire toutes les lignes de la requête externe. Cela les mettra en mémoire tampon dans le client MySQL, donc du point de vue du serveur, votre application a récupéré le jeu de résultats complet. Ensuite, vous pouvez exécuter plus de requêtes même dans une boucle de récupération de lignes à partir du jeu de résultats externe désormais mis en mémoire tampon.

Ou vous mysqli_result::fetch_all() qui renvoie le jeu de résultats complet sous forme de tableau PHP, puis vous pouvez boucler sur ce tableau.

L'appel de procédures stockées est un cas particulier, car une procédure stockée a le potentiel de renvoyer plusieurs ensembles de résultats, chacun pouvant avoir son propre ensemble de lignes. C'est pourquoi la réponse de @ a1ex07 mentionne l'utilisation de mysqli_multi_query() et en boucle jusqu'à mysqli_next_result() n'a plus d'ensembles de résultats. Ceci est nécessaire pour satisfaire le protocole MySQL, même si dans votre cas votre procédure stockée a un seul jeu de résultats.

PS :Au fait, je vois que vous faites des requêtes imbriquées parce que vous avez des données représentant une hiérarchie. Vous voudrez peut-être envisager de stocker les données différemment, afin de pouvoir les interroger plus facilement. J'ai fait une présentation à ce sujet intitulée Modèles pour les données hiérarchiques avec SQL et PHP . J'aborde également ce sujet dans un chapitre de mon livre Antipatterns SQL :éviter les pièges de la base de données Programmation .

Voici comment implémenter mysqli_next_result() dans CodeIgnitor 3.0.3 :

À la ligne 262 de system/database/drivers/mysqli/mysqli_driver.php changer

protected function _execute($sql)
{
    return $this->conn_id->query($this->_prep_query($sql));
}

à ça

protected function _execute($sql)
{
    $results = $this->conn_id->query($this->_prep_query($sql));
    @mysqli_next_result($this->conn_id); // Fix 'command out of sync' error
    return $results;
}

C'est un problème depuis la version 2.x. Je viens de mettre à jour vers 3.x et j'ai dû copier ce hack vers la nouvelle version.