Perintah tidak sinkron; Anda tidak dapat menjalankan perintah ini sekarang


93

Saya mencoba menjalankan kode PHP saya, yang memanggil dua kueri MySQL melalui mysqli, dan mendapatkan pesan kesalahan "Perintah tidak sinkron; Anda tidak dapat menjalankan perintah ini sekarang".

Ini kode yang saya gunakan

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

Saya telah mencoba membaca tentang ini, tetapi saya tidak yakin apa yang harus dilakukan. Saya telah membaca tentang hasil toko dan hasil gratis, namun tidak ada bedanya saat menggunakannya. Saya tidak yakin pada titik mana kesalahan ini terjadi, dan ingin tahu mengapa itu terjadi, dan bagaimana cara memperbaikinya.

Dengan pernyataan debug saya, loop if pertama untuk countQuery bahkan tidak dimasukkan, karena kesalahan dalam sintaks sql saya dekat dekat '% ? %'. Namun jika saya hanya memilih *alih-alih mencoba membatasi berdasarkan klausa LIKE, saya masih mendapatkan perintah dari kesalahan sinkronisasi.

Jawaban:


114

Anda tidak dapat memiliki dua kueri secara bersamaan karena mysqli menggunakan kueri tanpa buffer secara default (untuk pernyataan yang sudah disiapkan; sebaliknya untuk vanilla mysql_query). Anda dapat mengambil yang pertama ke dalam array dan mengulanginya, atau memberi tahu mysqli untuk menyangga kueri (menggunakan $stmt->store_result()).

Lihat di sini untuk detailnya.


3
Saya setuju, mysqli agak rusak otaknya. Ini tidak melakukan hal yang benar dengan driver PDO mysql sekalipun.

17
Anda dapat memiliki dua kueri secara bersamaan - Anda hanya perlu menjalankan. $stmt->store_result();Saya pikir tanggapan Anda harus membuatnya lebih jelas.
Bayangan

3
Butuh waktu lama bagi saya untuk menemukan informasi ini - tidak ada tempat yang mudah ditampilkan. Terima kasih. Saya baru saja memisahkan pertanyaan saya dengan $select_stmt->close();untuk membaginya (tidak simultan tetapi prosedural
n34_panda

@flussence, Anda menyatakan bahwa "mysqli menggunakan kueri tanpa buffer secara default". Jadi bagaimana kita bisa mengaturnya menjadi sebaliknya?
Pacerier

1
Saya tahu sepertinya aneh, tetapi saya mengalami kesalahan ini saat menjalankan kueri dengan mysqli_query melanggar kunci asing ... jadi jika ini terjadi pada siapa pun, periksa kembali apakah kueri INSERT Anda tidak melanggar kunci asing apa pun
lucaferrario

34

Saya memecahkan masalah ini di aplikasi C saya - inilah cara saya melakukannya:

  1. Mengutip dari forum mysql:

    Kesalahan ini terjadi saat Anda menghentikan kueri dengan pemisah titik koma di dalam aplikasi . Meskipun diperlukan untuk menghentikan kueri dengan pemisah titik koma saat menjalankannya dari baris perintah atau di browser kueri, hapus pemisah dari kueri di dalam aplikasi Anda.

  2. Setelah menjalankan kueri saya dan menangani hasil [C API: mysql_store_result()], saya mengulangi hasil yang berpotensi tertunda lebih lanjut yang terjadi melalui beberapa eksekusi pernyataan SQL seperti dua atau lebih pernyataan pilih (kembali ke belakang tanpa berurusan dengan hasil).

    Faktanya adalah bahwa prosedur saya tidak mengembalikan banyak hasil tetapi database tidak mengetahuinya sampai saya mengeksekusi: [C API: mysql_next_result()]. Saya melakukan ini dalam satu lingkaran (untuk ukuran yang baik) sampai mengembalikan bukan nol. Saat itulah penangan koneksi saat ini tahu tidak apa-apa untuk menjalankan kueri lain (saya menyimpan cache penangan saya untuk meminimalkan overhead koneksi).

    Ini adalah loop yang saya gunakan:

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

Saya tidak tahu PHP tapi saya yakin itu mirip.


11
Ini untukku. Di PHP saya baru saja menambahkan: while (mysqli_next_result ($ con));
Josh

Terima kasih atas jawaban yang memecahkan masalah saya. Saya menghapus pembatas dan berhasil. Saya tidak membebaskan (mengambil) atau menyimpan hasil saya, tetapi menutup kursor dan membangun kembali setelah saya menyelesaikan satu pernyataan kueri.
Chen Xie

@ Josh, Bagaimana melakukannya di mysqlekstensi lama ?
Pacerier

1
Menghapus titik koma di akhir kueri memperbaiki masalah "Perintah tidak sinkron; Anda tidak dapat menjalankan perintah ini sekarang" saat menggunakan Python MySQLdb.
Genom

17

Saya memiliki masalah yang sama hari ini, tetapi hanya ketika bekerja dengan prosedur tersimpan. Ini membuat kueri berperilaku seperti kueri multi, jadi Anda perlu "menggunakan" hasil lain yang tersedia sebelum membuat kueri lain.

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

Ini adalah poin yang signifikan: prosedur tersimpan mengembalikan hasil yang ditetapkan di atas dan di atas hasil apa pun yang mengatur kode di SP yang mungkin dihasilkan. Anda harus menanganinya atau mendapatkan kesalahan ini: stackoverflow.com/a/2315229/4495850
Richard

11

Saya memanggil fungsi ini setiap kali sebelum menggunakan $ mysqli-> query Bekerja dengan prosedur yang tersimpan juga.

function clearStoredResults(){
    global $mysqli;

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

}

5

Setelah Anda menggunakan

stmt->execute();

Anda MUNGKIN menutupnya untuk menggunakan kueri lain.

stmt->close();

Masalah ini memburuku selama berjam-jam. Mudah-mudahan, ini akan memperbaiki milik Anda.


1
Menutup pernyataan itu tidak perlu. Seperti yang dijawab @stalinbeltran di atas, kita perlu "mengonsumsi" hasil pernyataan sebelum menyiapkan yang lain. Jadi, $stmt1->execute(); $stmt2=$conn->prepare(...)akan memberikan kesalahan ini, tetapi $stmt1->execute(); $result1=$stmt1->get_result(); $stmt2=$conn->prepare(...)akan berfungsi dengan baik.
Jay Dadhania

Bro itu membantu saya terima kasih. f setiap orang yang mengatakan ini dan itu, saya menggunakan mysqli_prepare dua kali sebelum menutup yang pertama. Berhasil.
Abhinash Majhi

2

Saya menggunakan CodeIgniter. Satu server Oke ... yang ini mungkin lebih tua ... Pokoknya menggunakan

$this->db->reconnect();

Diperbaiki.


7
Bagaimana ini mengatasi masalah tersebut?
Jeremy J Starcher

4
@Norman, Ini tidak "memperbaiki" masalah. Itu hanya menghindarinya dengan membuang seluruh koneksi dan menghubungkan kembali. Ini sama sekali tidak masuk akal dari sudut pandang kinerja.
Pacerier

1

Masalahnya adalah pustaka C klien MySQL, tempat sebagian besar API MySQL dibuat. Masalahnya adalah pustaka C tidak mendukung eksekusi kueri secara bersamaan, jadi semua API yang dibangun di atasnya juga tidak. Bahkan jika Anda menggunakan kueri tanpa buffer. Inilah salah satu alasan mengapa API MySQL asinkron ditulis. Ini berkomunikasi langsung dengan server MySQL menggunakan TCP dan protokol kabel melakukannya mendukung query simultan.

Solusi Anda adalah dengan memodifikasi algoritme sehingga Anda tidak perlu keduanya dalam proses sekaligus, atau mengubahnya untuk menggunakan kueri yang di-buffer, yang mungkin merupakan salah satu alasan asli keberadaannya di pustaka C (yang lainnya adalah untuk sediakan semacam kursor).


1
Saya tidak perlu keduanya dalam proses sekaligus, saya senang countQuery selesai sepenuhnya sebelum kueri kedua saya, tetapi saya tidak yakin bagaimana cara menghentikan countQuery yang sedang berlangsung

Anda tidak mengambil data apa pun dari countQuery, itulah mengapa data itu masih 'dalam proses'. Ambil semua baris, atau ubah menjadi SELECT COUNT (ARTICLE_NO) dan dapatkan baris itu. Kemudian kueri kedua Anda akan berjalan.
staticsan

Saat Anda mengatakan "API MySQL asinkron", API mana yang Anda maksud? Juga, saya tidak mendapatkan kesimpulan Anda. "Masalah" ini bisa diperbaiki tanpa perlu API menjadi asynchronous.
Pacerier

1
Sejujurnya @Pacerier, saya juga tidak yakin lagi dengan apa yang saya maksud! Banyak yang telah terjadi dalam enam tahun dalam konektivitas MySQL jadi apa pun yang saya pikir saya maksud mungkin telah diganti namanya dan / atau dimasukkan ke dalam beberapa driver baru lainnya.
staticsan

1

untuk mengatasi masalah ini Anda harus menyimpan data hasil sebelum menggunakannya

$numRecords->execute();

$numRecords->store_result();

itu saja


1

Penyebab lain: store_result () tidak dapat dipanggil dua kali.

Misalnya, dalam kode berikut, Kesalahan 5 dicetak.

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

(Ini mungkin tidak relevan dengan kode sampel asli, tetapi dapat relevan untuk orang yang mencari jawaban atas kesalahan ini.)


1

Inilah MASALAH SAYA !!!

Pengikatan param adalah "dinamis" jadi saya memiliki variabel yang menetapkan parameter data untuk menggunakan bind_param . Jadi variabel itu salah tapi bukannya menampilkan kesalahan seperti "data param salah" justru mengatakan "tidak sinkron bla bla bla" jadi saya bingung ...


0

Saya pikir masalahnya adalah Anda membuat koneksi baru dalam fungsi tersebut, dan kemudian tidak menutupnya di akhir. Mengapa Anda tidak mencoba meneruskan koneksi yang ada dan menggunakannya kembali?

Kemungkinan lainnya adalah Anda kembali keluar dari tengah pengambilan loop sementara. Anda tidak pernah menyelesaikan pengambilan luar itu.


1
Jika saya membuat $ con global (yang merupakan praktik yang buruk tetapi harus berfungsi seperti yang Anda jelaskan) saya masih memiliki kesalahan yang sama.

1
saya tidak berpikir memiliki koneksi global adalah praktik yang buruk
Mathieu J.

0

Periksa untuk melihat apakah Anda mengetik semua parameter dengan benar. Ini melempar kesalahan yang sama jika jumlah parameter yang ditentukan dan kemudian diteruskan ke fungsi berbeda.


0

Ini tidak terkait dengan pertanyaan awal, tetapi saya memiliki pesan kesalahan yang sama dan utas ini adalah hit pertama di Google dan saya butuh beberapa saat untuk mencari tahu apa Masalahnya, jadi mungkin berguna untuk orang lain:

Saya TIDAK menggunakan mysqli, masih menggunakan mysql_connect saya punya beberapa pertanyaan sederhana, tetapi SATU kueri menyebabkan semua pertanyaan lain gagal dalam Koneksi yang sama.

Saya menggunakan mysql 5.7 dan php 5.6 saya memiliki tabel dengan tipe data "JSON". jelas, versi-php saya tidak mengenali nilai kembalian dari mysql (php hanya tidak tahu apa yang harus dilakukan dengan JSON-Format karena modul mysql bawaan terlalu tua (setidaknya menurut saya))

untuk saat ini saya mengubah JSON-Field-Type menjadi Text (seperti untuk saat ini saya tidak memerlukan fungsionalitas JSON mysql asli) dan semuanya berfungsi dengan baik


0

Jika Anda menggunakan kumpulan hasil Buffered atau Unbuffered untuk mengambil data, pertama-tama Anda harus menghapus data yang diambil dari memori, setelah Anda mengambil semua data . Karena Anda tidak dapat menjalankan prosedur MYSQL lain pada koneksi yang sama sampai Anda menghapus memori yang diambil. Tambahkan fungsi di bawah ini di ujung kanan skrip Anda, sehingga ini akan menyelesaikan masalah

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

Referensi dari dokumentasi PHP


1
Jika Anda tidak memerlukan beberapa catatan, Anda seharusnya tidak memilihnya sejak awal. Alih-alih hanya membebaskan mereka, jangan pilih mereka sama sekali. Dan jika tidak demikian dan Anda mengambil semua record yang dipilih, maka tidak akan ada kesalahan seperti itu sama sekali, tidak perlu memanggil close () atau free (). Pada prosedur yang tersimpan, ada metode yang tidak terlalu biadab, yang dijelaskan dalam jawaban di atas
Akal

0

Saya mengalami kesalahan ini menggunakan Doctrine DBAL QueryBuilder.

Saya membuat kueri dengan QueryBuilder yang menggunakan subpilihan kolom, juga dibuat dengan QueryBuilder. Subpilihan hanya dibuat melalui $queryBuilder->getSQL()dan tidak dijalankan. Terjadi kesalahan saat membuat subpilihan kedua. Dengan menjalankan sementara setiap subselect $queryBuilder->execute()sebelum menggunakan $queryBuilder->getSQL(), semuanya bekerja. Seolah-olah koneksi$queryBuilder->connection tetap dalam keadaan tidak valid untuk membuat SQL baru sebelum menjalankan SQL yang saat ini disiapkan, meskipun ada instance QueryBuilder baru di setiap subpilihan.

Solusi saya adalah menulis subpilihan tanpa QueryBuilder.


0

Saya menggunakan ODBC, dan perbaikan ini berfungsi untuk saya: ODBC -> tab System DSN -> klik dua kali untuk mengkonfigurasi sumber data saya -> detail -> tab Cursor -> Hapus centang [Jangan cache hasil dari kursor forward-only] - > klik Ok


0

Saya sering mengalami kesalahan ini dan selalu ketika saya menjalankan prosedur tersimpan yang saya telah debugging di phpmyadmin atau SQL Workbench (Saya bekerja di php menghubungkan dengan mysqli).

Hasil kesalahan dari fakta bahwa debugging melibatkan penyisipan pernyataan SELECT pada titik-titik strategis dalam kode untuk memberi tahu saya status variabel, dll. Menjalankan prosedur tersimpan yang menghasilkan beberapa kumpulan hasil dalam lingkungan klien ini baik-baik saja, tetapi menghasilkan " Perintah tidak sinkron "kesalahan saat dipanggil dari php. Solusinya adalah selalu memberikan komentar atau menghapus pilihan debugging sehingga prosedur hanya memiliki satu rangkaian hasil.


-1

Masalah saya adalah bahwa saya menggunakan pernyataan persiapkan pertama dan kemudian saya menggunakan kueri mysqli pada halaman yang sama dan mendapatkan kesalahan "Perintah tidak sinkron; Anda tidak dapat menjalankan perintah ini sekarang". Kesalahan itu baru terjadi ketika saya menggunakan kode yang telah menyiapkan pernyataan.

Yang saya lakukan adalah menutup pertanyaan itu. dan itu berhasil.

mysqli_stmt_close ($ stmt);

Kode saya

get_category.php (di sini menggunakan pernyataan persiapan)

    <?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 (di sini 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>

Sesuatu yang baru saja terlintas di benak saya, saya juga menambahkan variabel koneksi melalui global $ connection ;. Jadi saya pikir pada dasarnya satu set sistem kueri baru sedang dimulai setelah mengakhiri pernyataan persiapkan dengan mysqli_stmt_close ($ stmt); dan juga saya menambahkan file ini dan hal lainnya melalui penyertaan


get_category.php (di sini menggunakan pernyataan persiapan) pastebin.com/BiWysdYz admin_get_category_body.php (di sini mysqli) pastebin.com/Pwm30icm Catatan: Tidak dapat memposting semua kode karena batasan
Mahad Ali

Sesuatu yang baru saja terlintas di benak saya, saya juga menambahkan variabel koneksi melalui global $ connection ;. Jadi saya pikir pada dasarnya satu set sistem query baru sedang dimulai setelah mengakhiri pernyataan persiapkan dengan mysqli_stmt_close ($ stmt); dan juga saya menambahkan file ini dan hal lainnya melalui penyertaan.
Mahad Ali

-1

Ini adalah pertanyaan lama, tetapi tidak ada jawaban yang diposting berfungsi dalam kasus saya, saya menemukan bahwa dalam kasus saya, saya telah memilih dan memperbarui pada tabel dalam prosedur saya yang tersimpan, tabel yang sama memiliki pemicu pembaruan yang dipicu dan memicu prosedur menjadi loop tak terbatas. Setelah bug ditemukan, kesalahan tersebut hilang.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.