web-dev-qa-db-fra.com

Commandes désynchronisées; vous ne pouvez pas exécuter cette commande maintenant

J'essaie d'exécuter mon PHP code, qui appelle deux requêtes MySQL via mysqli, et j'obtiens le message d'erreur "Commandes non synchronisées; vous ne pouvez pas exécuter cette commande maintenant".

Voici le code que j'utilise

<?php
$con = mysqli_connect("localhost", "user", "password", "db");
if (!$con) {
    echo "Can't connect to MySQL Server. Errorcode: %s\n". Mysqli_connect_error();
    exit;
}
$con->query("SET NAMES 'utf8'");
$brand ="o";
$countQuery = "SELECT ARTICLE_NO FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE % ? %";
if ($numRecords = $con->prepare($countQuery)) {
    $numRecords->bind_param("s", $brand);
    $numRecords->execute();
    $data = $con->query($countQuery) or die(print_r($con->error));
    $rowcount = $data->num_rows;
    $rows = getRowsByArticleSearch("test", "Auctions", " ");
    $last = ceil($rowcount/$page_rows);
}  else {

print_r($con->error);
}
foreach ($rows as $row) {
    $pk = $row['ARTICLE_NO'];
    echo '<tr>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['USERNAME'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="updateByPk(\'Layer2\', \'' . $pk . '\')">'.$row['shortDate'].'</a></td>' . "\n";
    echo '<td><a href="#" onclick="deleterec(\'Layer2\', \'' . $pk . '\')">DELETE RECORD</a></td>' . "\n";
    echo '</tr>' . "\n";
}
function getRowsByArticleSearch($searchString, $table, $max) {
    $con = mysqli_connect("localhost", "user", "password", "db");
    $recordsQuery = "SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate FROM AUCTIONS WHERE upper(ARTICLE_NAME) LIKE '%?%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s')" . $max;
    if ($getRecords = $con->prepare($recordsQuery)) {
        $getRecords->bind_param("s", $searchString);
        $getRecords->execute();
        $getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate);
        while ($getRecords->fetch()) {
            $result = $con->query($recordsQuery);
            $rows = array();
            while($row = $result->fetch_assoc()) {
                $rows[] = $row;
            }
            return $rows;
        }
    }
}

J'ai essayé de lire à ce sujet, mais je ne sais pas quoi faire. J'ai lu des articles sur les résultats en magasin et les résultats gratuits, mais ils ne font aucune différence lors de leur utilisation. Je ne sais pas exactement à quel point cette erreur est causée et je voudrais savoir pourquoi et comment la réparer.

En passant par mes instructions de débogage, la première boucle if pour countQuery n’est même pas entrée, en raison d’une erreur dans ma syntaxe SQL proche de '% ? %'. Cependant, si je sélectionne simplement * au lieu d'essayer de limiter en fonction d'une clause LIKE, j'obtiens toujours la commande hors erreur de synchronisation.

84
Joshxtothe4

Vous ne pouvez pas avoir deux requêtes simultanées car mysqli utilise par défaut des requêtes sans tampon (pour les instructions préparées, c'est l'inverse pour Vanilla mysql_query). Vous pouvez soit chercher le premier dans un tableau et le parcourir en boucle, soit dire à mysqli de mettre les requêtes en mémoire tampon (avec $stmt->store_result() ).

Voir ici pour plus de détails.

104
user42092

J'ai résolu ce problème dans mon application C - voici comment je l'ai fait:

  1. Citant des forums mysql:

    Cette erreur survient lorsque vous mettez fin à votre requête avec un séparateur de point-virgule dans l'application. Bien qu'il soit nécessaire de mettre fin à une requête avec un séparateur point-virgule lors de son exécution à partir de la ligne de commande ou du navigateur de requêtes, supprimez le délimiteur de la requête dans votre application.

  2. Après avoir exécuté ma requête et traité les résultats [API C: mysql_store_result()], je répète tous les résultats potentiellement en attente résultant de l'exécution de plusieurs instructions SQL, telles que deux ou plusieurs instructions de sélection (dos à dos sans traiter avec les résultats).

    Le fait est que mes procédures ne renvoient pas plusieurs résultats, mais que la base de données ne le sait pas tant que je n'ai pas exécuté: [C API: mysql_next_result()]. Je fais cela dans une boucle (pour faire bonne mesure) jusqu'à ce qu'il retourne différent de zéro. C'est à ce moment que le gestionnaire de connexion actuel sait qu'il est correct d'exécuter une autre requête (je mets en cache mes gestionnaires pour réduire le temps système nécessaire à la connexion).

    C'est la boucle que j'utilise:

    for(; mysql_next_result(mysql_handler) == 0;) 
      /* do nothing */;
    

Je ne sais pas PHP mais je suis sûr qu'il a quelque chose de similaire.

31
tracy.brown

J'ai eu aujourd'hui le même problème, mais uniquement lorsque vous travaillez avec une procédure stockée. Cela fait que la requête se comporte comme une requête multiple, vous devez donc "consommer" d'autres résultats disponibles avant de créer une autre requête.

while($this->mysql->more_results()){
    $this->mysql->next_result();
    $this->mysql->use_result();
}
15
stalin beltran

J'appelle cette fonction à chaque fois avant d'utiliser $ mysqli-> query Fonctionne également avec les procédures stockées.

function clearStoredResults(){
    global $mysqli;

    do {
         if ($res = $mysqli->store_result()) {
           $res->free();
         }
        } while ($mysqli->more_results() && $mysqli->next_result());        

}
7
Juergen

J'utilise CodeIgniter. Un serveur OK ... celui-ci probablement plus ancien ... Quoi qu'il en soit en utilisant

$this->db->reconnect();

Fixe le.

2
Norman

Une fois que vous avez utilisé

stmt->execute();

Vous devez le fermer pour utiliser une autre requête.

stmt->close();

Ce problème me cherchait pendant des heures. J'espère que ça va réparer le vôtre.

2
Carl James

Pour ceux que les réponses précédentes n'ont pas aidé ... voici ce qui était mon problème !!!

la liaison des paramètres était "dynamique", donc j'avais une variable qui définit les paramètres des données afin d'utiliser bind_param. Donc, cette variable était fausse, mais au lieu de lancer une erreur du type "données param incorrectes", il est écrit "désynchronisé bla bla bla" et j'ai été confus ...

J'espère que ça a aidé quelqu'un!

1
Ari Waisberg

Le problème est la bibliothèque client MySQL, sur laquelle sont construites la plupart des API MySQL. Le problème est que la bibliothèque C ne prend pas en charge l'exécution simultanée de requêtes, donc toutes les API construites au-dessus ne le sont pas non plus. Même si vous utilisez des requêtes sans mémoire tampon. C'est l'une des raisons pour lesquelles l'API MySQL asynchrone a été écrite. Il communique directement avec le serveur MySQL en utilisant TCP et le protocole fil fait) supporte les requêtes simultanées.

Votre solution consiste à modifier l’algorithme afin de ne pas avoir les deux en même temps en cours ou de les modifier pour utiliser des requêtes en mémoire tampon, ce qui est probablement l’une des raisons originales de leur existence dans la bibliothèque C (l’autre consiste à: fournir une sorte de curseur).

1
staticsan

pour résoudre ce problème, vous devez stocker les résultats avant de les utiliser

$numRecords->execute();

$numRecords->store_result();

c'est tout

1
Nader Ben Mabrouk

Je pense que le problème est que vous établissez une nouvelle connexion dans la fonction et que vous ne la fermez pas à la fin. Pourquoi n'essayez-vous pas de transmettre la connexion existante et de la réutiliser?

Une autre possibilité est que vous reveniez au milieu d'une extraction de boucle while. Vous ne terminez jamais cette recherche externe.

0
Paul Tomblin

Ce n'est pas lié à la question initiale, mais j'avais le même message d'erreur et ce fil est le premier hit de Google. Il m'a fallu un certain temps pour comprendre le problème, afin qu'il puisse être utile à d'autres:

je n'utilise pas mysqli, j'utilise toujours mysql_connect. J'avais quelques requêtes simples, mais UNE requête entraînait l'échec de toutes les autres requêtes dans la même connexion.

J'utilise mysql 5.7 et php 5.6 j'ai eu une table avec le type de données "JSON". évidemment, ma version php ne reconnaissait pas la valeur de retour de mysql (php ne savait simplement pas quoi faire avec le format JSON car le module mysql intégré était trop ancien (du moins, je pense))

pour l'instant j'ai changé le type de champ JSON en texte (pour l'instant je n'ai pas besoin de la fonctionnalité JSON mysql native) et tout fonctionne bien

0
mech

Si vous utilisez le jeu de résultats Buffered ou Unbuffered pour récupérer les données, vous devez d'abord effacer les données extraites de la mémoire, une fois que vous avez récupéré toutes les données. Comme vous ne pouvez pas exécuter une autre procédure MYSQL sur la même connexion jusqu'à ce que vous effaciez la mémoire extraite. Ajoutez cette fonction ci-dessous à l'extrémité droite de votre script, ainsi le problème sera résolu

$numRecords->close(); or $numRecords->free(); // This clears the referencing memory, and will be ready for the next MYSQL fetch

Référence de la PHP documentation

0
Kaz

Vérifiez si vous saisissez tous les paramètres correctement. La même erreur est générée si le nombre de paramètres définis, puis transmis à la fonction, est différent.

0
Mixtelf

J'ai rencontré cette erreur en utilisant Doctrine DBAL QueryBuilder.

J'ai créé une requête avec QueryBuilder qui utilise des sous-colonnes, également créées avec QueryBuilder. Les sous-sélections ont été créées uniquement via $queryBuilder->getSQL() et n'ont pas été exécutées. L'erreur s'est produite lors de la création de la deuxième sous-sélection. En exécutant provisoirement chaque sous-sélection avec $queryBuilder->execute() avant d'utiliser $queryBuilder->getSQL(), tout a fonctionné. C'est comme si la connexion $queryBuilder->connection reste dans un état non valide pour la création d'un nouveau SQL avant d'exécuter le SQL actuellement préparé, malgré la nouvelle instance de QueryBuilder sur chaque sous-sélection.

Ma solution était d'écrire les sous-éléments sans QueryBuilder.

0
Fabian Picone