对示例 1 的建议改进。
原因
如果返回数据/结果集,multi_query 才会返回非假响应,并且只检查输入的第一个查询。将第一个 SELECT 查询与 INSERT 查询互换会导致示例过早退出,并显示消息“Multi query failed: (0)”。
该示例假设一旦第一个查询没有失败,其他查询也已成功。或者更确切地说,它只是退出而没有报告第一个查询之后的某个查询失败,因为如果查询失败,next_result 返回 false。
示例中的更改是在创建字符串 $sql 之后进行的。
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "连接 MySQL 失败: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if (!$mysqli->query("DROP TABLE IF EXISTS test") || !$mysqli->query("CREATE TABLE test(id INT)")) {
echo "创建表失败: (" . $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; ";
// 从这里开始修改示例 1
// 不用检查 multi_query 的结果,因为它将在第一个查询没有返回数据时返回 false,即使查询本身成功了。
$mysqli->multi_query($sql);
do // while (true); // 只有在发生错误或没有更多查询要处理时退出
{
// 检查当前正在处理的查询是否失败
if (0 !== $mysqli->errno)
{
echo "多查询失败: (" . $mysqli->errno . ") " . $mysqli->error;
break;
}
// 存储并可能处理查询的结果,
// store_result 和 use_result 都将为不返回结果的查询返回 false(例如 INSERT)
if(false !== ($res = $mysqli->store_result() )
{
var_dump($res->fetch_all(MYSQLI_ASSOC));
$res->free();
}
// 如果没有更多查询要处理,则退出循环
if (false === ($mysqli->more_results() )
{
break;
}
// 获取要处理的下一个查询的结果
// 不用检查结果的成功/失败,
// 因为在循环开始时有一个错误检查和
// 报告块。
$mysqli->next_result()
} while (true); // 只有在发生错误或没有更多查询要处理时退出
?>
请注意,普通的 while ($mysqli->more_results() && $mysqli->next_result() 已被两个检查和 while (true); 替换。
这是因为 next_result 在有问题的查询失败时会返回 false。
因此,要么需要在 while 循环之后进行最后一次检查以查看是否发生了错误,要么需要将不同的操作分开。
示例中的更改执行了拆分。