【PHP+MySQLi】PHPでmysqli_multi_query()を使って複数テーブルに対してDELETE、INSERTを合計300ほど行うような処理をしているのですが、この処理の後に別にクエリを発行すると「Commands out of sync」というエラーが発生します。


mysqli_multi_query()のあとに

if(mysqli_more_results($link)){
while(mysqli_next_result($link)){ ; }
}

を入れてクエリの結果をすべてはき出させるとエラーが出なくなることはわかったのですが、無限ループを作っていますし、これでは効率が悪い気がしています。

mysqli_multi_query()の結果をすべて1度に消去する、または取得する方法はないでしょうか? よろしくお願いします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2007/01/13 01:07:41
  • 終了:2007/01/18 13:48:37

ベストアンサー

id:bonlife No.2

回答回数421ベストアンサー獲得回数752007/01/18 13:43:57

ポイント80pt

前回の回答は適切ではありませんでした。申し訳ありません。

調べてみたところ、mysqli_multi_query()で処理を行う場合、質問文中で試していらっしゃる例のように、LOOPで処理をするしかなさそうです。

MySQLのマニュアルを調べたところ、以下のような記述がありました。

If you enable CLIENT_MULTI_STATEMENTS or CLIENT_MULTI_RESULTS, you should process the result for every call to mysql_query() or mysql_real_query() by using a loop that calls mysql_next_result() to determine whether there are more results. For an example, see Section 24.2.9, “C API Handling of Multiple Statement Execution”.

PHPのソースコードを確認していないのですが、 mysqli_multi_query は内部でMySQLのコネクションに CLIENT_MULTI_STATEMENTS オプションを指定していると思われます。

この場合、上記の説明にある通り、すべてのmysql_query()、mysql_real_query()ごとにmysql_next_result()をループで呼ぶ必要があります。

If you enable multiple-statement support, you should process the results from mysql_query() and mysql_real_query() within a loop that checks for more results. This is true even for statements such as DROP TABLE that return a result but not a result set. Failure to process the result this way may result in a dropped connection to the server.

上記にある通り、たとえDROP TABLEのようなresult setは返さなくてもresultを返す場合でも、ループでの処理は必要です。

これは、INSERT、DELETEにも当てはまります。

望んでいた回答ではないかもしれませんが、少しでも参考になれば幸いです。

id:heppokoA

なるほど,やはりループが必要ということですね。詳しく引用していただいてありがとうございます。とても参考になりました。

それでは質問を終了しようとおもいます。

2007/01/18 13:47:13

その他の回答(1件)

id:bonlife No.1

回答回数421ベストアンサー獲得回数752007/01/13 16:42:27

ポイント20pt

消去したいのであれば、mysqli_free_resultで結果に関連付けられたメモリを開放すれば良いはずです。

[参考URL]

id:heppokoA

ありがとうございます。

mysqli_multi_query()ではbool値しか返ってこないようなのですが、mysqli_free_result()に渡すmysqli_resultオブジェクトはどこから持ってくればよいのでしょうか? ひょっとして引数なしでも実行できたりするのでしょうか? 一応、時間があるときに試してみたいと思います。

引き続きみなさんからの回答をお待ちしています。

- - 追記 - -

やはり,「PHP Warning: Wrong parameter count for mysql_free_result()」となります。仮にmysql_multi_query()からの返り値を渡しても,返り値がbool値なので,「PHP Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource」となります。

2007/01/18 11:07:10
id:bonlife No.2

回答回数421ベストアンサー獲得回数752007/01/18 13:43:57ここでベストアンサー

ポイント80pt

前回の回答は適切ではありませんでした。申し訳ありません。

調べてみたところ、mysqli_multi_query()で処理を行う場合、質問文中で試していらっしゃる例のように、LOOPで処理をするしかなさそうです。

MySQLのマニュアルを調べたところ、以下のような記述がありました。

If you enable CLIENT_MULTI_STATEMENTS or CLIENT_MULTI_RESULTS, you should process the result for every call to mysql_query() or mysql_real_query() by using a loop that calls mysql_next_result() to determine whether there are more results. For an example, see Section 24.2.9, “C API Handling of Multiple Statement Execution”.

PHPのソースコードを確認していないのですが、 mysqli_multi_query は内部でMySQLのコネクションに CLIENT_MULTI_STATEMENTS オプションを指定していると思われます。

この場合、上記の説明にある通り、すべてのmysql_query()、mysql_real_query()ごとにmysql_next_result()をループで呼ぶ必要があります。

If you enable multiple-statement support, you should process the results from mysql_query() and mysql_real_query() within a loop that checks for more results. This is true even for statements such as DROP TABLE that return a result but not a result set. Failure to process the result this way may result in a dropped connection to the server.

上記にある通り、たとえDROP TABLEのようなresult setは返さなくてもresultを返す場合でも、ループでの処理は必要です。

これは、INSERT、DELETEにも当てはまります。

望んでいた回答ではないかもしれませんが、少しでも参考になれば幸いです。

id:heppokoA

なるほど,やはりループが必要ということですね。詳しく引用していただいてありがとうございます。とても参考になりました。

それでは質問を終了しようとおもいます。

2007/01/18 13:47:13

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません