建議對範例 1 的改進。
原因
Multi_query 僅在返回資料/結果集時才返回非 false 的回應,並且僅檢查輸入的第一個查詢。將第一個 SELECT 查詢與 INSERT 查詢交換將導致範例提前退出,並顯示訊息「多重查詢失敗:(0)」。
該範例假設一旦第一個查詢未失敗,則其他查詢也已成功。或者更確切地說,它只是在沒有報告第一個查詢之後的其中一個查詢失敗的情況下退出,因為如果查詢失敗,next_result 會返回 false。
範例中的更改是在建立字串 $sql 之後進行的。
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")) {
echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
$sql = "SELECT COUNT(*) AS _num FROM test; ";
$sql.= "INSERT INTO test(id) VALUES (1); ";
$sql.= "SELECT COUNT(*) AS _num FROM test; ";
// changes to example 1 start here
// don't bother checking the result from multi_query since it will return false
// if the first query does not return data even if the query itself succeeds.
$mysqli->multi_query($sql);
do // while (true); // exit only on error or when there are no more queries to process
{
// check if query currently being processed hasn't failed
if (0 !== $mysqli->errno)
{
echo "Multi query failed: (" . $mysqli->errno . ") " . $mysqli->error;
break;
}
// store and possibly process result of the query,
// both store_result & use_result will return false
// for queries that do not return results (INSERT for example)
if(false !== ($res = $mysqli->store_result() )
{
var_dump($res->fetch_all(MYSQLI_ASSOC));
$res->free();
}
// exit loop if there ar no more queries to process
if (false === ($mysqli->more_results() )
{
break;
}
// get result of the next query to process
// don't bother to check for success/failure of the result
// since at the start of the loop there is an error check &
// report block.
$mysqli->next_result()
} while (true); // exit only on error or when there are no more queries to process
?>
請注意,正常的 while ($mysqli->more_results() && $mysqli->next_result() 已被兩個檢查和 while (true) 取代;
這是由於如果相關查詢失敗,next_result 將返回 false 的「問題」所致。
因此,需要在 while 迴圈之後進行最後一次檢查以檢查是否有錯誤,或者必須將不同的操作分開。
範例中的更改執行了拆分。