PHPからMySQLのストアドを連続して呼び出すとクエリが失敗する件。
まずは普通に Stored Procedure を実行してみる。
(接続を貼る部分は省略)
1 2 3 4 5 6 7 8 9 10 |
// ストアド実行1 $q = " call stored_proc1(); "; $result = mysqli_query($link, $q); if (!$result) { die('クエリーが失敗しました。['.$q.'] '.mysqli_error($link)); } while ($row = mysqli_fetch_assoc($result)) { echo $row['field_name']; } mysqli_free_result($result); |
これはうまくいく。
でも上記の直後にストアド2を実行するコードを追加すると、クエリが失敗する。
1 2 3 4 5 6 7 8 9 10 |
// ストアド実行2 $q = " call stored_proc2(); "; $result = mysqli_query($link, $q); if (!$result) { die('クエリーが失敗しました。['.$q.'] '.mysqli_error($link)); } while ($row = mysqli_fetch_assoc($result)) { echo $row['field_name']; } mysqli_free_result($result); |
Commands out of sync; you can’t run this command now
なにこれ??
mysqli_free_result の直後に、mysqli_next_result() を追加することで回避できた。
1 2 3 4 |
mysqli_free_result($result); if( mysqli_more_results($link) ){ mysqli_next_result($link); } |
マニュアルによると mysqli_next_result() は
直近の mysqli_multi_query() コールから次の結果セットを用意します。
これは mysqli_store_result() あるいは mysqli_use_result() で取得することが可能です。
とのこと。mysqli_multi_query() は使ってないのだが…。
結果セット2の中身は?
ストアドの実行結果などが入るのかな、と思ってvar_dumpしてみたりしたが、結果セットはなさそうである。
まとめ?
色々調べたが直接の原因はわからなかった。
とにかく、
PHP(mysqli)からストアドを実行すると、
結果セット1(ストアドの結果)
結果セット2(中身なし)
の2つが得られて、結果セット2へ「mysqli_next_result」しないで次のストアドを Call しようとするとエラー
ということらしい。
エラー対策入れた版
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// ストアド実行1 $q = " call stored_proc1(); "; $result = mysqli_query($link, $q); if (!$result) { die('クエリーが失敗しました。['.$q.'] '.mysqli_error($link)); } while ($row = mysqli_fetch_assoc($result)) { echo $row['field_name']; } mysqli_free_result($result); if( mysqli_more_results($link) ){ mysqli_next_result($link); } |