コマンドが同期していません。このコマンドは今実行できません


94

mysqliを介して2つのMySQLクエリを呼び出すPHPコードを実行しようとしていますが、「コマンドが同期していません。現在、このコマンドを実行できません」というエラーが表示されます。

これが私が使っているコードです

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

私はこれについて読んでみましたが、何をすべきかわかりません。ストア結果とフリー結果について読んだのですが、どちらを使っても違いはありません。このエラーがどの時点で発生しているのか正確にはわかりません。なぜこのエラーが発生しているのか、またその修正方法を知りたいのですが。

私のデバッグステートメントを見てみると、countQueryの最初のifループが開始されていません'% ? %'。これは、SQL構文のエラーがnearに近いためです。ただし*、LIKE句に基づいて制限しようとするのではなく単に選択した場合でも、コマンドの同期エラーが発生します。

回答:


115

mysqliはデフォルトでバッファリングされていないクエリを使用するため、2つのクエリを同時に実行することはできません(準備されたステートメントの場合、これはvanillaの反対ですmysql_query)。最初のものを配列にフェッチしてループするか、mysqliにクエリをバッファするように指示することができます(を使用$stmt->store_result())。

詳細はこちらをご覧ください。


3
私は同意します、mysqliは少し脳の損傷を受けています。それはありませんけれどもPDOのMySQLドライバで正しいことを行います。

17
2つのクエリを同時に実行することでき$stmt->store_result();ます。実行する必要があるのは、応答がそれをより明確にするはずです。
シャドウ

3
この情報を見つけるために年齢を重ねる-どこに簡単に表示されるかはわかりません。ありがとう。クエリ$select_stmt->close();を分割し て分割します(同時ではなく手続き型
n34_panda

@flussence、あなたは「mysqliはデフォルトでバッファされていないクエリを使用する」と述べました。それでは、他の方法で設定するにはどうすればよいでしょうか。
パセリエ2015年

1
奇妙に思われますが、mysqli_queryで外部キーに違反するクエリを実行しているときにこのエラーが発生しました...そのため、これが誰かに発生した場合は、INSERTクエリが外部キーに違反していないことを再確認してください
lucaferrario

33

私は私のCアプリケーションでこの問題を解決しました-ここに私がそれをした方法があります:

  1. mysqlフォーラムからの引用:

    このエラーは、アプリケーション内でセミコロン区切り文字を使用してクエリを終了すると発生します。コマンドラインまたはクエリブラウザからクエリを実行する場合は、セミコロン区切り文字でクエリを終了する必要がありますが、アプリケーション内のクエリから区切り文字を削除してください。

  2. クエリを実行して結果を処理した後(C API mysql_store_result():)、2つ以上のselectステートメントなどの複数のSQLステートメントの実行によって発生する可能性のある保留中の結果を繰り返し処理します(結果を処理せずに戻る)。

    実際のところ、私のプロシージャは複数の結果を返さないのですが、データベースは、[C API:mysql_next_result()] を実行するまでそれを知りません。ゼロ以外の値が返されるまで、ループで(適切な方法で)これを実行します。これは、現在の接続ハンドラーが別のクエリを実行してもよいことがわかったときです(接続のオーバーヘッドを最小限に抑えるためにハンドラーをキャッシュします)。

    これは私が使用するループです:

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

PHPはわかりませんが、PHPに似たものがあると確信しています。


11
これで終わりです。PHPでは、次のように追加しました:while(mysqli_next_result($ con));
Josh

私の問題を解決した答えをありがとう。区切り文字を削除しましたが、機能します。結果を解放(フェッチ)したり保存したりはしませんでしたが、クエリのステートメントが1つ終了したら、カーソルを閉じて再構築しました。
Chen Xie

@ジョシュ、それをレガシーmysql拡張でどうやって行うの?
Pacerier、2015

1
クエリの最後でセミコロンを削除すると、Python MySQLdbを使用しているときの「コマンドが同期しません。このコマンドを現在実行できません」という問題が修正されました。
ゲノム

17

今日も同じ問題がありましたが、ストアドプロシージャで作業しているときのみです。これにより、クエリはマルチクエリのように動作するため、別のクエリを作成する前に、他の結果を「消費」する必要があります。

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

これは重要なポイントです。ストアドプロシージャは、SPのコードが生成する可能性のある結果セットに加えて、結果セットを返します。これを処理するか、このエラーを取得する必要があります。stackoverflow.com
Richard

11

$ mysqli-> queryを使用する前に毎回この関数を呼び出します。ストアドプロシージャでも機能します。

function clearStoredResults(){
    global $mysqli;

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

}

5

使用したら

stmt->execute();

あなたは、MAY、別のクエリを使用して閉じます。

stmt->close();

この問題は何時間も私を狩っていました。うまくいけば、それはあなたを修正します。


1
ステートメントを閉じる必要はありません。@stalinbeltranが上記で回答したように、ステートメントを準備する前にステートメントの結果を「消費」する必要があります。したがって、$stmt1->execute(); $stmt2=$conn->prepare(...)このエラーが発生しますが、問題なく$stmt1->execute(); $result1=$stmt1->get_result(); $stmt2=$conn->prepare(...)機能します。
ジェイダダニア2013年

ブロさん、ありがとうございました。これとあれを言う人すべてのために、私はmysqli_prepareを2回使用してから最初の1つを閉じました。できます。
Abhinash Majhi

2

私はCodeIgniterを使用しています。1つのサーバーでOK ...これはおそらく古いサーバーです...とにかく

$this->db->reconnect();

修正しました。


7
これはどのように問題に対処しますか?
ジェレミーJスターチャー

4
@ノーマン、これは問題を「修正」しません。接続全体を破棄し、再接続することで回避します。これは、パフォーマンスの観点からはまったく意味がありません。
パセリエ2015年

1

問題は、ほとんどのMySQL APIが構築されているMySQLクライアントCライブラリです。問題は、Cライブラリがクエリの同時実行をサポートしていないため、その上に構築されたすべてのAPIもサポートしないことです。バッファリングされていないクエリを使用する場合でも。これが、非同期のMySQL APIが作成された理由の1つです。TCPを使用してMySQLサーバーと直接通信し、ワイヤープロトコル同時クエリをサポートします。

解決策は、両方を同時に進行させる必要がないようにアルゴリズムを変更するか、バッファクエリを使用するように変更することです。これはおそらくCライブラリに存在する元の理由の1つです(もう1つは、一種のカーソルを提供します)。


1
私は一度に進行中の両方を持っている必要はありません、私はcountQueryは私の2番目のクエリの前に完全に終えることのために満足しているが、私はproggressであることからcountQueryを停止する方法がわからないよ

countQueryからデータを取得していないため、まだ「進行中」です。すべての行を取得するか、それをSELECT COUNT(ARTICLE_NO)に変更してその行を取得します。次に、2番目のクエリが実行されます。
staticsan 2009年

「非同期MySQL API」と言うとき、どのAPIを指しますか?また、私はあなたの結論を得ていません。この「問題」は、APIを非同期にすることなく修正できます。
パセリエ2015年

1
@Pacerier正直に言うと、私が何を言っているのかもうよくわかりません!MySQL接続では6年間で多くのことが起こったので、私が言及していると思っていたものはすべて、名前が変更されているか、他の新しいドライバーに組み込まれていると思われます。
staticsan 2015年

1

この問題を解決するには、使用する前に結果データを保存する必要があります

$numRecords->execute();

$numRecords->store_result();

それで全部です


1

別の原因:store_result()を2回呼び出すことはできません。

たとえば、次のコードでは、エラー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);

(これは元のサンプルコードには関係ないかもしれませんが、このエラーへの回答を求めている人には関係する可能性があります。)


1

これが私の問題でした!!!

paramバインディングは「動的」だったので、bind_paramを使用するためにデータのparamsを設定する変数がありました。そのため、その変数は間違っていましたが、「間違ったパラメーターデータ」のようなエラーをスローする代わりに、「非同期bla bla bla」というメッセージが表示されたため、混乱しました...


0

問題は、関数で新しい接続を作成していて、最後にそれを閉じていないことだと思います。既存の接続を渡して再利用してみませんか?

別の可能性は、whileループのフェッチの途中から戻っていることです。その外部フェッチを完了することはありません。


1
$ conをグローバルにした場合(これは悪い習慣ですが、説明どおりに機能するはずです)でも同じエラーが発生します。

1
グローバルなつながりを持つことは悪い習慣だとは思いません
Mathieu J.

0

すべてのパラメーターを正しく入力しているかどうかを確認してください。定義されてから関数に渡されるパラメーターの量が異なる場合、同じエラーをスローします。


0

これは元の質問とは関係ありませんが、同じエラーメッセージがあり、このスレッドがGoogleで最初にヒットし、問題が何であるかを理解するのにしばらく時間がかかったため、他の人に役立つかもしれません。

私はmysqliを使用していませんが、まだmysql_connectを使用していますが、いくつかの単純なクエリがありましたが、1つのクエリが原因で、同じ接続内で他のすべてのクエリが失敗しました。

私はmysql 5.7とphp 5.6を使用していますが、データ型「JSON」のテーブルがありました。明らかに、私のphp-versionはmysqlからの戻り値を認識しませんでした(組み込みのmysql-moduleが古すぎるため、phpはJSON-Formatの処理方法を知りませんでした(少なくとも私は思う))

今のところ、JSON-Field-TypeをTextに変更しました(今のところ、ネイティブのmysql JSON機能は必要ありません)。すべてが正常に機能します


0

データのフェッチにBufferedまたはUnbufferedの結果セットを使用する場合、すべてのデータをフェッチしたら、まず、フェッチしたデータをメモリからクリアするだけです。フェッチしたメモリをクリアするまで、同じ接続で別のMYSQLプロシージャを実行することはできません。これをスクリプトの右下に追加して、問題解決します

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

PHPドキュメントからの参照


1
一部のレコードが必要ない場合は、最初にレコードを選択するべきではありません。それらを解放するのではなく、単にそれらを選択しないでください。そうでない場合で、選択したすべてのレコードをフェッチすると、そのようなエラーはまったく発生せず、close()またはfree()を呼び出す必要もありません。ストアドプロシージャの時点で、上記の回答で説明されている、それほど野蛮な方法はありません
常識

0

Doctrine DBAL QueryBuilderを使用してこのエラーに遭遇しました。

列の副選択を使用するQueryBuilderでクエリを作成しました。これもQueryBuilderで作成しました。副選択はによってのみ作成され$queryBuilder->getSQL()、実行されませんでした。2番目の副選択の作成時にエラーが発生しました。$queryBuilder->execute()を使用する前にで各副選択を暫定的に実行することにより$queryBuilder->getSQL()、すべてが機能しました。$queryBuilder->connection各副選択の新しいQueryBuilderインスタンスにもかかわらず、現在準備されているSQLを実行する前に、新しいSQLを作成するための接続が無効な状態のままであるかのようです。

私の解決策は、QueryBuilderなしで副選択を記述することでした。


0

ODBCを使用していて、この修正が機能します。ODBC->タブシステムDSN->ダブルクリックしてデータソースを構成します->詳細->タブカーソル-> [前方スクロールカーソルの結果をキャッシュしない]をオフにします - > OKをクリック


0

私はよくこのエラーに遭遇し、phpmyadminまたはSQL Workbenchでデバッグしていたストアドプロシージャを実行するときはいつでも(mysqliと接続しているphpで作業しています)。

エラーの原因は、変数の状態などを通知するために、コード内の重要なポイントにSELECTステートメントを挿入することによるデバッグです。これらのクライアント環境で複数の結果セットを生成するストアドプロシージャを実行することは問題ありませんが、 " PHPから呼び出されたとき、コマンドが同期しない」エラー。解決策は常にコメントアウトするか、デバッグ選択を削除して、プロシージャに結果セットが1つだけになるようにすることです。


-1

私の問題は、最初のprepareステートメントを使用していて、同じページでmysqliクエリを使用していて、「コマンドが同期していません。このコマンドを現在実行できない」というエラーが発生することでした。エラーが発生したのは、prepareステートメントを含むコードを使用していたときだけでした。

私がしたことは質問を閉じることでした。そしてそれは働いた。

mysqli_stmt_close($ stmt);

私のコード

get_category.php(ここでは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(ここでは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>

ちょうど私の心を超えた何か、私はまたグローバル$ connection;を介して接続変数を追加しています。したがって、基本的には、mysqli_stmt_close($ stmt);でprepareステートメントを終了した後に、まったく新しいクエリシステムのセットが開始されていると思います。また、これらのファイルやその他のものをインクルードで追加しています


get_category.php(ここでステートメントを準備使用)pastebin.com/BiWysdYz admin_get_category_body.php(ここではmysqliの) pastebin.com/Pwm30icm 注:缶が原因の制限にすべてのコードを投稿していない
Mahadアリ

ちょうど私の心を越えた何か、私はまたグローバル$ connection;を介して接続変数を追加しています。したがって、基本的には、mysqli_stmt_close($ stmt);でprepareステートメントを終了した後に、まったく新しいクエリシステムのセットが開始されていると思います。また、これらのファイルやその他のものをインクルードで追加しています。
マハドアリ

-1

これは古い質問ですが、投稿された回答が私の場合は機能しませんでした。私の場合、ストアドプロシージャのテーブルを選択して更新しました。同じテーブルに更新トリガーがあり、トリガーされ、プロシージャを無限ループにします。バグが見つかったら、エラーはなくなりました。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.