Comandi non sincronizzati; non puoi eseguire questo comando ora


94

Sto cercando di eseguire il mio codice PHP, che chiama due query MySQL tramite mysqli, e ricevo l'errore "Comandi non sincronizzati; non puoi eseguire questo comando ora".

Ecco il codice che sto usando

<?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;
        }
    }
}

Ho provato a leggere su questo, ma non sono sicuro di cosa fare. Ho letto dei risultati del negozio e dei risultati gratuiti, tuttavia questi non hanno fatto differenza quando li si utilizza. Non sono sicuro del punto esatto in cui è stato causato questo errore e vorrei sapere perché è stato causato e come risolverlo.

Seguendo le mie istruzioni di debug, il primo ciclo if per countQuery non viene nemmeno inserito, a causa di un errore nella mia sintassi sql vicino a near '% ? %'. Tuttavia, se seleziono semplicemente *invece di provare a limitare in base a una clausola LIKE, ottengo ancora l'errore di sincronizzazione del comando.

Risposte:


115

Non puoi avere due query simultanee perché mysqli utilizza query senza buffer per impostazione predefinita (per le istruzioni preparate; è l'opposto per vanilla mysql_query). Puoi recuperare il primo in un array e farlo scorrere, o dire a mysqli di memorizzare nel buffer le query (usando $stmt->store_result()).

Vedi qui per i dettagli.


3
Sono d'accordo, mysqli è un po 'danneggiato al cervello. Si fa fare la cosa giusta con il driver MySQL DOP però.

17
È possibile avere due interrogazioni simultanee - è sufficiente per eseguire $stmt->store_result();penso che la tua risposta dovrebbe rendere più chiaro che.
Shadow

3
Mi ci sono voluti anni per trovare queste informazioni - non dove sono facilmente visualizzate. Grazie. Ho appena separato le mie query con $select_stmt->close();per dividerle (non simultaneamente ma procedurale
n34_panda

@flussence, hai affermato che "mysqli utilizza query senza buffer per impostazione predefinita". Quindi come possiamo impostarlo per fare altrimenti?
Pacerier

1
So che sembra strano, ma ho avuto questo errore durante l'esecuzione di una query con mysqli_query che viola una chiave esterna ... quindi se questo accade a qualcuno, controlla che la tua query INSERT non stia violando alcuna chiave esterna
lucaferrario

33

Ho risolto questo problema nella mia applicazione C - ecco come l'ho fatto:

  1. Citando dai forum di mysql:

    Questo errore si verifica quando si termina la query con un delimitatore punto e virgola all'interno dell'applicazione . Sebbene sia necessario terminare una query con un delimitatore punto e virgola quando viene eseguita dalla riga di comando o nel browser delle query, rimuovere il delimitatore dalla query all'interno dell'applicazione.

  2. Dopo aver eseguito la mia query e aver gestito i risultati [API C: mysql_store_result() ], itero su qualsiasi altro risultato potenzialmente in sospeso che si verifica tramite l'esecuzione di più istruzioni SQL come due o più istruzioni select (back to back senza occuparsi dei risultati).

    Il fatto è che le mie procedure non restituiscono più risultati ma il database non lo sa finché non eseguo: [C API: mysql_next_result() ]. Lo faccio in un ciclo (per buona misura) finché non restituisce un valore diverso da zero. Questo è il momento in cui il gestore della connessione corrente sa che va bene eseguire un'altra query (memorizzo nella cache i miei gestori per ridurre al minimo il sovraccarico della connessione).

    Questo è il ciclo che uso:

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

Non conosco PHP ma sono sicuro che abbia qualcosa di simile.


11
Questo è stato per me. In PHP ho appena aggiunto: while (mysqli_next_result ($ con));
Josh

Grazie per la risposta che ha risolto il mio problema. Ho rimosso il delimitatore e funziona. Non ho liberato (recuperato) o archiviato i miei risultati, ma ho chiuso il cursore e ricostruito una volta terminata un'istruzione di query.
Chen Xie

@ Josh, come farlo mysqlnell'estensione legacy ?
Pacerier

1
La rimozione del punto e virgola alla fine della query ha risolto il problema "Comandi non sincronizzati; non è possibile eseguire questo comando ora" quando si utilizza Python MySQLdb.
Genoma

17

Oggi ho avuto lo stesso problema, ma solo lavorando con una stored procedure. In questo modo la query si comporta come una query multipla, quindi è necessario "consumare" altri risultati disponibili prima di eseguire un'altra query.

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

Questo è un punto significativo: le stored procedure restituiscono un set di risultati al di sopra di qualsiasi set di risultati che il codice nell'SP potrebbe generare. Devi gestirlo o ottenere questo errore: stackoverflow.com/a/2315229/4495850
Richard

11

Chiamo questa funzione ogni volta prima di usare $ mysqli-> query Funziona anche con le stored procedure.

function clearStoredResults(){
    global $mysqli;

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

}

5

Una volta che hai usato

stmt->execute();

Si POTREBBE chiuderlo per usare un'altra query.

stmt->close();

Questo problema mi stava dando la caccia per ore. Si spera che risolva il tuo.


1
Non è necessario chiudere la dichiarazione. Come ha risposto @stalinbeltran sopra, dobbiamo "consumare" il risultato di un'istruzione prima di prepararne un'altra. Quindi, $stmt1->execute(); $stmt2=$conn->prepare(...)darebbe questo errore, ma $stmt1->execute(); $result1=$stmt1->get_result(); $stmt2=$conn->prepare(...)funzionerebbe perfettamente.
Jay Dadhania

Fratello, mi ha aiutato a ringraziarti. Per tutti quelli che dicono questo e quello, ho usato mysqli_prepare due volte prima di chiudere il primo. Funziona.
Abhinash Majhi

2

Uso CodeIgniter. Un server OK ... questo probabilmente più vecchio ... Comunque in uso

$this->db->reconnect();

Aggiustato.


7
Come risolve il problema?
Jeremy J Starcher

4
@ Norman, questo non "risolve" il problema. Lo evita semplicemente buttando via l'intera connessione e ricollegandosi di nuovo. Questo non ha alcun senso dal punto di vista delle prestazioni.
Pacerier

1

Il problema è la libreria C del client MySQL, su cui si basa la maggior parte delle API MySQL. Il problema è che la libreria C non supporta l'esecuzione simultanea di query, quindi anche tutte le API costruite sopra non lo fanno. Anche se utilizzi query senza buffer. Questo è uno dei motivi per cui è stata scritta l'API MySQL asincrona. Comunica direttamente con il server MySQL utilizzando TCP e il filo-protocollo non supporta query simultanee.

La tua soluzione è modificare l'algoritmo in modo che non sia necessario averli entrambi in corso contemporaneamente, o cambiarli per utilizzare query bufferizzate, che è probabilmente una delle ragioni originali della loro esistenza nella libreria C (l'altra è quella di fornire una sorta di cursore).


1
Non ho bisogno di avere entrambi in corso contemporaneamente, sono felice che countQuery finisca completamente prima della mia seconda query, ma non sono sicuro di come impedire a countQuery di essere in proggress

Non stai recuperando alcun dato da countQuery, ecco perché è ancora "in corso". Recupera tutte le righe o cambialo in SELECT COUNT (ARTICLE_NO) e ottieni quella riga. Quindi verrà eseguita la seconda query.
staticsan

Quando dici "l'API MySQL asincrona", a quale API ti riferisci? Inoltre, non sto ottenendo la tua conclusione. Questo "problema" può essere risolto senza che l'API sia asincrona.
Pacerier

1
Ad essere onesti, @Pacerier non sono nemmeno più sicuro di quello che volevo dire! Sono successe molte cose in sei anni nella connettività MySQL, quindi qualunque cosa pensassi di riferirmi è stata probabilmente rinominata e / o incorporata in qualche altro nuovo driver.
staticsan

1

per risolvere questo problema è necessario memorizzare i dati dei risultati prima di utilizzarli

$numRecords->execute();

$numRecords->store_result();

È tutto


1

Un'altra causa: store_result () non può essere chiamato due volte.

Ad esempio, nel codice seguente, viene stampato l'errore 5.

<?php

$db = new mysqli("localhost", "something", "something", "something");

$stmt = $db->stmt_init();
if ($stmt->error) printf("Error 1 : %s\n", $stmt->error);

$stmt->prepare("select 1");
if ($stmt->error) printf("Error 2 : %s\n", $stmt->error);

$stmt->execute();
if ($stmt->error) printf("Error 3 : %s\n", $stmt->error);

$stmt->store_result();
if ($stmt->error) printf("Error 4 : %s\n", $stmt->error);

$stmt->store_result();
if ($stmt->error) printf("Error 5 : %s\n", $stmt->error);

(Questo potrebbe non essere rilevante per il codice di esempio originale, ma può essere rilevante per le persone che cercano risposte a questo errore.)


1

Ecco qual era il MIO PROBLEMA !!!

Il param binding era "dinamico", quindi avevo una variabile che imposta i parametri dei dati per poter utilizzare bind_param . Quindi quella variabile era sbagliata ma invece di lanciare un errore come "dati param errati" dice "fuori sincronia bla bla bla" quindi ero confuso ...


0

Penso che il problema sia che stai creando una nuova connessione nella funzione e quindi non la chiudi alla fine. Perché non provi a passare la connessione esistente e riutilizzarla?

Un'altra possibilità è che tu stia tornando nel mezzo di un recupero del ciclo while. Non completi mai quel recupero esterno.


1
Se creo $ con globale (che è una cattiva pratica ma dovrebbe funzionare come descrivi) ho ancora lo stesso errore.

1
Non credo che avere una connessione globale sia una cattiva pratica
Mathieu J.

0

Controlla se stai digitando correttamente tutti i parametri. Genera lo stesso errore se la quantità di parametri definiti e poi passati alla funzione è diversa.


0

Questo non è correlato alla domanda originale, ma ho ricevuto lo stesso messaggio di errore e questo thread è il primo successo in Google e mi ci è voluto un po 'per capire quale fosse il problema, quindi potrebbe essere utile per altri:

NON sto usando mysqli, ancora usando mysql_connect ho avuto alcune semplici query, ma UNA query ha causato il fallimento di tutte le altre query all'interno della stessa connessione.

Uso mysql 5.7 e php 5.6 avevo una tabella con il tipo di dati "JSON". ovviamente, la mia versione php non riconosceva il valore restituito da mysql (php semplicemente non sapeva cosa fare con il formato JSON perché il modulo mysql integrato era troppo vecchio (almeno credo))

per ora ho cambiato il JSON-Field-Type in Text (dato che per ora non ho bisogno della funzionalità JSON nativa di mysql) e tutto funziona bene


0

Se si utilizza un set di risultati con buffer o senza buffer per il recupero dei dati, è necessario innanzitutto cancellare i dati recuperati dalla memoria, una volta recuperati tutti i dati . Poiché non è possibile eseguire un'altra procedura MYSQL sulla stessa connessione finché non si cancella la memoria recuperata. Aggiungi questa funzione sotto alla fine del tuo script, così risolverà il problema

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

Riferimento dalla documentazione PHP


1
Se non hai bisogno di alcuni record, non avresti dovuto selezionarli in primo luogo. Invece di liberarli semplicemente, non selezionarli affatto. E se non è il caso e hai recuperato tutti i record selezionati, allora non ci sarà alcun errore del genere e non è necessario chiamare close () o free (). Per quanto riguarda le procedure memorizzate, esiste un metodo meno barbaro, descritto nelle risposte sopra
Il tuo buon senso

0

Mi sono imbattuto in questo errore utilizzando Doctrine DBAL QueryBuilder.

Ho creato una query con QueryBuilder che utilizza sottoselezioni di colonna, anch'esse create con QueryBuilder. Le sottoselezioni sono state create solo tramite $queryBuilder->getSQL()e non eseguite. L'errore si è verificato durante la creazione della seconda sottoselezione. Eseguendo provvisoriamente ogni sottoselezione con $queryBuilder->execute()prima dell'uso $queryBuilder->getSQL(), tutto ha funzionato. È come se la connessione $queryBuilder->connectionrimanesse in uno stato non valido per la creazione di un nuovo SQL prima di eseguire l'SQL attualmente preparato, nonostante la nuova istanza di QueryBuilder su ciascuna sottoselezione.

La mia soluzione era scrivere le sottoselezioni senza QueryBuilder.


0

Sto usando ODBC e questa correzione funziona per me: ODBC -> scheda DSN di sistema -> doppio clic per configurare la mia origine dati -> dettagli -> scheda Cursori -> Deseleziona [Non memorizzare nella cache i risultati dei cursori solo forward] - > fai clic su Ok


0

Mi capita spesso di riscontrare questo errore ed è sempre quando eseguo una stored procedure che ho eseguito il debug in phpmyadmin o SQL Workbench (sto lavorando in php connettendomi con mysqli).

L'errore deriva dal fatto che il debug comporta l'inserimento di istruzioni SELECT in punti strategici del codice per dirmi lo stato delle variabili, ecc. L'esecuzione di una procedura memorizzata che produce più set di risultati in questi ambienti client va bene, ma produce il " Comandi non sincronizzati "errore quando viene chiamato da php. La soluzione è sempre commentare o rimuovere le selezioni di debug in modo che la procedura abbia un solo set di risultati.


-1

Il mio problema era che stavo usando prima l'istruzione prepare e poi stavo usando la query mysqli sulla stessa pagina e ricevevo l'errore "Comandi non sincronizzati; non puoi eseguire questo comando ora". L'errore è stato solo allora quando stavo usando il codice che aveva l'istruzione prepare.

Quello che ho fatto è stato chiudere la domanda. e ha funzionato.

mysqli_stmt_close ($ stmt);

Il mio codice

get_category.php (qui usando l'istruzione prepare)

    <?php


    global $connection;
    $cat_to_delete =    mysqli_real_escape_string($connection, $_GET['get'] );

    $sql = "SELECT category_name FROM categories WHERE category_id = ? ;";


    $stmt = mysqli_stmt_init($connection);

    if (!mysqli_stmt_prepare($stmt, $sql))
        $_SESSION['error'] = "Error at preaparing for deleting query. mysqli_stmt_error($stmt) ." & redirect('../error.php');

    mysqli_stmt_bind_param($stmt, 's', $cat_to_delete);

    if (!mysqli_stmt_execute($stmt))
        $_SESSION['error'] = "ERror at executing delete category ".mysqli_stmt_error($stmt) &
            redirect('../error.php');


    mysqli_stmt_bind_result($stmt, $cat_name);

    if (!mysqli_stmt_fetch($stmt)) {
        mysqli_stmt_error($stmt);
    }



    mysqli_stmt_free_result($stmt);
    mysqli_stmt_close($stmt);

admin_get_category_body.php (qui mysqli)

        <?php

        if (isset($_GET['get']) && !empty($_GET['get']) )
        {
            include 'intodb/edit_category.php';
        }


        if (check_method('get') && isset($_GET['delete']) )
        {
            require 'intodb/delete_category.php';
        }


        if (check_method('get') && isset($_GET['get']) )
        {
            require 'intodb/get_category.php';
        }


        ?>

        <!--            start: cat body          -->

        <div     class="columns is-mobile is-centered is-vcentered">
            <div class="column is-half">
                <div   class="section has-background-white-ter box ">


                    <div class="has-text-centered column    " >
                        <h4 class="title is-4">Ctegories</h4>
                    </div>

                    <div class="column " >


                        <?php if (check_method('get') && isset($_GET['get'])) {?>
                        <form action="" method="post">
                            <?php } else {?>
                            <form action="intodb/add_category.php" method="post">
                                <?php } ?>

                                <label class="label" for="admin_add_category_bar">Add Category</label>
                                <div class="field is-grouped">

                                    <p class="control is-expanded">

                                        <?php if (check_method('get') && isset($_GET['get'])) {?>

                                            <input id="admin_add_category_bar" name="admin_add_category_bar_edit" class="input" type="text" placeholder="Add Your Category Here" value="<?php echo $cat_name; ?>">

                                            <?php


                                            ?>
                                        <?php } else {?>
                                            <input id="admin_add_category_bar" name="admin_add_category_bar" class="input" type="text" placeholder="Add Your Category Here">

                                        <?php } ?>
                                    </p>
                                    <p class="control">
                                        <input type="submit" name="admin_add_category_submit" class="button is-info my_fucking_hover_right_arrow" value="Add Category">
                                    </p>
                                </div>
                            </form>


                            <div class="">

                                <!--            start: body for all posts inside admin          -->


                                <table class="table is-bordered">
                                    <thead>
                                    <tr>
                                        <th><p>Category Name</p></th>
                                        <th><p>Edit</p></th>
                                        <th><p>Delete</p></th>
                                    </tr>
                                    </thead>

                                    <?php

                                    global $connection;
                                    $sql = "SELECT * FROM categories ;";

                                    $result = mysqli_query($connection, $sql);
                                    if (!$result) {
                                        echo mysqli_error($connection);
                                    }
                                    while($row = mysqli_fetch_assoc($result))
                                    {
                                        ?>
                                        <tbody>
                                        <tr>
                                            <td><p><?php echo $row['category_name']?></p></td>
                                            <td>
                                                <a href="admin_category.php?get=<?php echo $row['category_id']; ?>" class="button is-info my_fucking_hover_right_arrow" >Edit</a>

                                            </td>

                                            <td>
                                                <a href="admin_category.php?delete=<?php echo $row['category_id']; ?>" class="button is-danger my_fucking_hover_right_arrow" >Delete</a>

                                            </td>
                                        </tr>


                                        </tbody>
                                    <?php }?>
                                </table>

                                <!--           end: body for all posts inside admin             -->




                            </div>

                    </div>
                </div>


            </div>

        </div>
        </div>

Qualcosa che mi è appena passato per la mente, sto anche aggiungendo di nuovo la variabile di connessione tramite la connessione $ globale ;. Quindi penso che fondamentalmente un intero nuovo set di sistema di query sia stato avviato dopo la fine dell'istruzione prepare con mysqli_stmt_close ($ stmt); e inoltre sto aggiungendo questi file e altre cose tramite include


get_category.php (qui usando l'istruzione prepare) pastebin.com/BiWysdYz admin_get_category_body.php (qui mysqli) pastebin.com/Pwm30icm Nota: non è possibile pubblicare tutto il codice a causa di limitazioni
Mahad Ali

Qualcosa che mi è appena passato per la mente, sto anche aggiungendo di nuovo la variabile di connessione tramite la connessione $ globale ;. Quindi penso che fondamentalmente un intero nuovo set di sistema di query sia stato avviato dopo la fine dell'istruzione prepare con mysqli_stmt_close ($ stmt); e inoltre sto aggiungendo questi file e altre cose tramite include.
Mahad Ali

-1

Questa è una vecchia domanda, ma nessuna delle risposte pubblicate ha funzionato nel mio caso, ho scoperto che nel mio caso avevo selezioni e aggiornamenti su una tabella nella mia stored procedure, la stessa tabella aveva un trigger di aggiornamento che veniva attivato e attivava il procedura in un ciclo infinito. Una volta individuato il bug, l'errore è scomparso.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.