在 mysqli 中存储和迭代查询结果

Posted

技术标签:

【中文标题】在 mysqli 中存储和迭代查询结果【英文标题】:Store and iterate over result of query in mysqli 【发布时间】:2013-12-24 05:57:55 【问题描述】:

这是我在 php 中的简单查询,使用 mysqli 面向对象的风格:

$query = "SELECT name FROM usertable WHERE id = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $id);
$id= $_GET['id'];
$stmt->execute();
$stmt->bind_result($name);

while($stmt->fetch())
   echo $name." ";


$stmt->free_result();
$stmt->close();

这很好用。我获得了从 select 语句中检索到的名称列表。

现在,虽然我想使用 $name 变量作为另一个查询的参数,但 mysqli 不允许这样做,因为我必须关闭第一个查询然后调用第二个查询。

所以我认为我必须存储第一个查询的结果,然后迭代调用新查询的结果。

我尝试了以下方法:

$query = "SELECT name FROM usertable WHERE id = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $id);
$id= $_GET['id'];
$stmt->execute();
//$stmt->bind_result($name);
$result = $stmt->store_result();
$stmt->free_result();
$stmt->close();

while ($row = $result->fetch_row()) 

    echo $row[0]." ";

但这不起作用。 while 里面的代码永远不会到达。

注意:我想避免使用multi_query()

【问题讨论】:

打开另一个数据库连接并在while循环中使用该连接进行查询 @Linger,如果使用单例模式获取连接变量怎么办? 听起来您应该简单地使用 JOIN 通过一个查询来查询所有数据。 @Mike 第二个查询可能是 INSERT 或 UPDATE,或某种组合。可能我可以加入所有查询,但为什么我不能遍历第一个查询的结果? @Joseph82,您应该能够打开到同一个数据库的两个不同连接。将一个连接用于初始查询,在 while 内执行语句时使用另一个连接。试试看它是否有效。 【参考方案1】:

mysqli_stmt::store_result 返回一个布尔值。根据文档,它应该是这样的:

$stmt->execute();
$stmt->store_result();

$stmt->bind_result($name);

while($stmt->fetch())
    //echo $name." ";
    // try another statement
    $query = "INSERT INTO usertable ...";
    $stmt2 = $mysqli->prepare($query);
    ...


$stmt->free_result();
$stmt->close();

如果这不起作用,您可以先将所有行提取到一个数组中,然后再次循环该数组:

$stmt->execute();
$stmt->bind_result($name);
$names = array();
while($stmt->fetch())
    $names[] = $name;

$stmt->free_result();
$stmt->close();

foreach($names as $name) 
    $query = "INSERT INTO usertable ...";
    $stmt = $mysqli->prepare($query);
    ...

【讨论】:

是的@redreggae,关于 store_result,你是对的。它只是返回一个布尔值。但是“手动”将结果存储在数组中似乎有点不正统。 如果使用不支持 get_result() 的 PHP 版本,您的解决方案很有用 好的,谢谢你的信息。我自己更喜欢 PDO,因为它更容易使用并且支持不同的数据库。所以我真的看不出为什么要使用mysqli。 是的@redreggae,也许 PDO 是更好的选择,特别是对于绑定参数。但是我只使用 mysql 数据库,所以目前,迁移到 PDO 不是优先事项。以后肯定会的:) @Joseph82 有趣的是,我对 PDO 和 MySql 做了同样的事情(在 fetch 循环中执行更新语句),没有问题。关于这个问题,我在文档中唯一能找到的是以下内容。 This method is useful for database drivers that do not support executing a PDOStatement object when a previously executed PDOStatement object still has unfetched rows...。 PDOStatement::closeCursor【参考方案2】:

我已经解决了这个问题:

$query = "SELECT name FROM usertable WHERE id = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $id);
$id= $_GET['id'];
$stmt->execute();
$result = $stmt->get_result();
$stmt->free_result();
$stmt->close();

while ($row = $result->fetch_array(MYSQLI_NUM)) 

    echo $row[0]." ";

只需使用get_result()fetch_array()

【讨论】:

get_result 仅在您安装了 mysqlnd 驱动程序的情况下才有效,否则您会收到错误消息。

以上是关于在 mysqli 中存储和迭代查询结果的主要内容,如果未能解决你的问题,请参考以下文章

如何使用循环绑定mysqli参数并将结果存储在数组中?

如何在另一个存储过程中调用一个存储过程(PHP 和 mysqli)

如何迭代引用虚拟图的 SPARQL 查询?

迭代存储过程 BigQuery 中的行

2个准备好的语句,2个存储过程,1个mysqli连接

DNS的递归查询和迭代查询