web-dev-qa-db-ja.com

同期していないコマンド。今このコマンドを実行することはできません

My_sqliを介して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;
        }
    }
}

私はこれを読んでみましたが、どうしたらいいかわかりません。ストア結果と無料結果について読みましたが、これらを使用しても違いはありません。このエラーがどの時点で発生したのか正確にはわかりません。なぜエラーが発生したのか、どのように修正するのかを知りたいです。

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

84
Joshxtothe4

Mysqliはデフォルトでバッファなしクエリを使用するため、2つの同時クエリを作成できません(準備済みステートメントの場合。Vanillamysql_queryの場合は逆です)。最初の配列をフェッチして配列にループするか、mysqliにクエリをバッファリングするように指示できます( $stmt->store_result() を使用)。

詳細については、 here をご覧ください。

104
user42092

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はわかりませんが、似たようなものがあるはずです。

31
tracy.brown

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

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

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

function clearStoredResults(){
    global $mysqli;

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

}
7
Juergen

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

$this->db->reconnect();

それを修正しました。

2
Norman

使用したら

stmt->execute();

別のクエリを使用するには、閉じる必要があります。

stmt->close();

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

2
Carl James

前の答えが役に立たなかった人のために...ここに私の問題がありました!!!

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

私はそれが誰かを助けたことを願っています!

1
Ari Waisberg

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

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

1
staticsan

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

$numRecords->execute();

$numRecords->store_result();

それで全部です

1

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

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

0
Paul Tomblin

これは元の質問とは関係ありませんが、同じエラーメッセージが表示され、このスレッドが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
mech

データのフェッチにバッファ付きまたはバッファなしの結果セットを使用する場合、まず、フェッチしたデータをメモリからクリアする必要がありますすべてのデータをフェッチしたら。フェッチされたメモリをクリアするまで、同じ接続で別のMYSQLプロシージャを実行できないため。これをスクリプトの右端に追加して、問題を解決するように​​します

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

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

0
Kaz

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

0
Mixtelf

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

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

私の解決策は、QueryBuilderなしでサブセレクトを書くことでした。

0
Fabian Picone