PHPを使用してMySQLデータベースを操作する場合、開発者はMySQLI拡張機能を使用して複雑なクエリを処理することができます。特に、ストアドプロシージャを呼び出したり、複数のSQLステートメントを実行したりする場合、 Next_Result()関数は特に重要です。この関数は、処理に使用されます。つまり、複数の結果がクエリ(複数の選択の出力やストアドプロシージャの出力など)で返される場合、 next_result()を介して通過できます。
ただし、複数の結果セットなしでnext_result()を呼び出すのは危険です。
次のようにSQLを実行するとき:
CALL get_user_and_orders(1);
このストアドプロシージャは、2つの結果セットを返す場合があります。
1つ目はユーザー情報です。
2つ目は、ユーザーの注文情報です。
これらの2つの結果セットを正しく取得するには、これを処理する必要があります。
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->multi_query("CALL get_user_and_orders(1)")) {
do {
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_assoc()) {
print_r($row);
}
$result->free();
}
} while ($mysqli->next_result());
}
ここでは、 next_result()が理にかなっています - 次の結果セットを読み取ろうとします。
実行するSQLが、単純なクエリなど、複数の結果を返さない場合:
$mysqli->multi_query("SELECT * FROM users WHERE id = 1");
この時点で、 next_result()を呼び出します。
$mysqli->next_result();
これは次のリスクをもたらす可能性があります。
next_result()自体はエラーを直接報告しませんが( falseを返します)、現在の結果を最初に正しく消費しない場合(store_result()calling store_result()など)、呼び出しは「同期しないコマンド」エラーを引き起こす可能性があります。
これは、mysqliの接続が誤った状態であり、内部PHPロジックが現在の結果を処理したかどうかがわからないためです。
現在の結果セットを明示的に処理してnext_result()に直接移動しない場合、MySQLサーバーはまだ以前の結果を読んでおらず、特に接続リソースの漏れを簡単に引き起こす可能性のあるループまたはバッチコールでリソースを保持すると考えています。
意味のないnext_result()は、複数の結果があると予想されるようにコードを見せることができますが、実際にはメンテナンスコストと誤解を招くのは論理的なエラーです。
次の場合にのみ、必ずnext_result()を使用してください。
Multi_Query()を使用するか、ストアドプロシージャを実行します。
SQLが複数の結果を返すことを確認します。
以前の結果セットは、next_result()が呼び出される前に消費されます。
また、次のロジックをカプセル化することもできます。
if ($mysqli->multi_query($sql)) {
do {
if ($result = $mysqli->store_result()) {
// 現在の結果セットを処理します
$result->free();
}
} while ($mysqli->more_results() && $mysqli->next_result());
}
この書き込みにより、 next_result()は、より多くの結果セットがある場合にのみ呼び出されます。これはより安全です。
複数の結果セットなしでnext_result()を呼び出すと、リソースの解放、同期外のエラー、論理的混乱などの問題が簡単につながる可能性があります。クエリ構造を必ず理解し、複数の結果セットを処理する必要があるかどうかを判断し、不必要な呼び出しを避けてください。
要するに、 next_result()はマルチリエルトセットを扱うための重要なツールですが、「それを正しく使用する」ことは「もっと使用する」よりも重要です。