使用mysqli在PHP中,“SELECT”命令的prepared statement失败。

3

我能够使用mysqli(在PHP中)执行多个预处理语句。但是,由于某种原因,当我尝试运行“SELECT”命令时,预处理语句总是会遇到错误。 例如,以下行将成功:

$stmt=$mysqli->prepare("UPDATE events SET category='m' WHERE id=(?)");

然而,以下一行将失败:

$stmt=$mysqli->prepare("SELECT * FROM events WHERE id=(?)");

当我说失败时,我的意思是下面三行代码将返回1,表明UPDATE命令更改了一行记录...

$stmt->bind_param('i',$id);
$stmt->execute();
echo $stmt->affected_rows;

下面三行代码将会返回 SELECT 的值为 0:
$stmt->bind_param('i',$id);
$stmt->execute();
echo $stmt->num_rows;

顺便说一下,我知道为单个SELECT准备语句并不是很有效 - 这个问题大多是学术性的。


用 $stmt->num_rows 代替 SELECT 命令中的 $stmt->affected_rows,结果为 0。所以这仍然没有解决问题——我期望得到 1。 - JMS
1
我知道对于单个SELECT语句,预处理语句并不是很高效 - 谁在建议这样做?它们的效率与任何SQL查询一样,没有更多也没有更少。 - Mark Baker
这似乎是许多博客中反复出现的观点。声称由于你必须两次与MySQL服务器通信(一次使用准备语句,然后第二次使用实际参数),所以双重通信会带来性能上的成本。您认为这种说法不正确吗? - JMS
1
执行函数会将语句和绑定变量一起发送给MySQL,而不是分为两个步骤。MySQL会识别它是一条预处理语句,并检查已编译的语句缓存。如果该语句已经在缓存中,则加载并使用它;如果没有,则编译该语句并将其存储在已编译的语句缓存中。然后将绑定变量添加到其执行中...仍然只有一个与数据库服务器的通信用于语句和绑定变量,而不是每个都有单独的通信。 - Mark Baker
感谢您的出色回答。 - JMS
3个回答

1
如果你这样做,你会得到什么?
echo $stmt->num_rows;

您不能对SELECT语句使用受影响行数方法!


谢谢 - 我得到了0。这不应该发生 - 我期望得到1。 - JMS
请看我的上面回答,你需要存储结果以获得非零值。 - Joe T

1
此函数(affected_rows)仅适用于更新表的查询。为了从SELECT查询中获取行数,请改用mysqli_stmt_num_rows()。

http://php.net/manual/en/mysqli-stmt.affected-rows.php

请确保先存储结果!!
$stmt->execute();

/* store result */
$stmt->store_result();

printf("Number of rows: %d.\n", $stmt->num_rows);

我认为最好的方法是按照这里的示例绑定结果并获取 http://php.net/manual/en/mysqli-stmt.fetch.php - Joe T

1

mysqli_affected_rows

返回最后一次INSERT、UPDATE、REPLACE或DELETE查询所影响的行数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接