以下を実行しようとしています。
<?php
$db = mysqli_connect("localhost","user","pw") or die("Database error");
mysqli_select_db($db, "database");
$agtid = $_POST['level'];
$sql = sprintf("call agent_hier(%d)", $agtid);
$result = mysqli_query($db, $sql) or exit(mysqli_error($db));
if ($result) {
echo "<table border='1'>
<tr><th>id</th>
<th>name</th>
<th>parent_id</th>
<th>parent_name</th>
<th>level</th>
<th>email</th></tr>";
while ($row = mysqli_fetch_assoc($result))
{
$aid = $row["id"];
$sql2 = "SELECT * FROM members WHERE MEMNO = '$aid'";
$result2 = mysqli_query($db,$sql2) or exit(mysqli_error($db));
while ($newArray = mysqli_fetch_array($result2)) {
$fname = $newArray['FNAME'];
$lname = $newArray['LNAME'];
$mi = $newArray['MI'];
$address = $newArray['ADDRESS'];
$city = $newArray['CITY'];
$state = $newArray['STATE'];
$Zip = $newArray['Zip'];
$kdate = $newArray['KDATE'];
$date = abs(strtotime(date('m/d/Y')) - strtotime(date($kdate))) / (60 * 60 * 24);
}
echo sprintf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",
$row["id"],$row["name"],
$row["parent_id"],$row["parent_name"],
$row["level"],$row["email"]);
}
echo "</table>";
}
mysqli_free_result($result);
mysqli_close($db);
?>
から行を削除すると:
$aid = $row["agent_id"];
に....
$date = abs(strtotime(date('m/d/Y')) - strtotime(date($kdate))) / (60 * 60 * 24);
}
すべてが正常に動作します。そうでない場合、次のエラーが発生します。
コマンドが同期していません。このコマンドは今実行できません
調査では、複数のMySQLiクエリが同時に実行されたことが原因であると考えられます。この場合、mysqli_multi_query
を使用しますが、すべてのサンプルと一般的なデータについて ガイド はそうではないようです該当します。
何か案は?
MySQLクライアントでは、進行中のクエリからフェッチされる行がまだある場合、新しいクエリを実行できません。一般的なエラーについては、MySQLドキュメントの Commands out of sync を参照してください。
mysqli_store_result()
を使用して、外部クエリからすべての行をプリフェッチできます。これにより、MySQLクライアントでそれらがバッファリングされるため、サーバーの観点からは、アプリは結果セット全体をフェッチします。その後、バッファリングされた外部結果セットから行をフェッチするループでも、より多くのクエリを実行できます。
または mysqli_result::fetch_all()
は、結果セット全体をPHP配列として返します。その後、その配列をループできます。
ストアドプロシージャの呼び出しは特殊なケースです。ストアドプロシージャには複数の結果セットが返される可能性があるため、それぞれに独自の行セットがある場合があるためです。 @ a1ex07からの回答がmysqli_multi_query()
の使用とmysqli_next_result()
に結果セットがなくなるまでループすることについて言及しているのはこのためです。ストアドプロシージャに単一の結果セットがある場合でも、これはMySQLプロトコルを満たすために必要です。
PS:ところで、階層を表すデータがあるので、ネストされたクエリを実行しているようです。より簡単にデータを照会できるように、データの格納方法を変えることを検討してください。私はこのタイトル SQLとPHPを使用した階層データのモデル に関するプレゼンテーションを行いました。このトピックについては、私の本の章でも説明しています SQLアンチパターン:データベースプログラミングの落とし穴を回避する 。
CodeIgnitor 3.0.3でmysqli_next_result()
を実装する方法は次のとおりです。
system/database/drivers/mysqli/mysqli_driver.php
変更の262行目
protected function _execute($sql)
{
return $this->conn_id->query($this->_prep_query($sql));
}
これに
protected function _execute($sql)
{
$results = $this->conn_id->query($this->_prep_query($sql));
@mysqli_next_result($this->conn_id); // Fix 'command out of sync' error
return $results;
}
これは2.x以降の問題です。私は3.xにアップデートし、このハックを新しいバージョンにコピーする必要がありました。
単に、mysqli_free_resultが呼び出された後、mysqli_next_result($ db)を呼び出す必要があります。
mysqli_free_result($ result); mysqli_next_result($ db) mysqli_close($ db);
この関数を呼び出すだけです:
$this->free_result();
function free_result() {
while (mysqli_more_results($this->conn) && mysqli_next_result($this->conn)) {
$dummyResult = mysqli_use_result($this->conn);
if ($dummyResult instanceof mysqli_result) {
mysqli_free_result($this->conn);
}
}
}
ストアドプロシージャによる以前の接続の保持を閉じる必要があります。毎回接続を閉じる代わりに、単に次のように使用できます:
mysqli_next_result($conn);