【问题标题】:fetch_assoc() works only once in a loopfetch_assoc() 在循环中只工作一次
【发布时间】:2019-11-01 03:41:24
【问题描述】:

我正在遍历 MySQL DB 中的 2 个表(使用 fetch_assoc())。我想在每次迭代中获取第一个表的当前 id 和第二个表的所有 id,但我只在第一次迭代时获得第二个表的 id。从第二次迭代开始,只返回第一个表的当前 id。我想知道我做错了什么。

我已经尝试过循环并在此处查找了类似的问题,但没有一个真正有帮助。

<?php
$my_sqli = new mysqli('localhost', 'root', '', 'taskpro') or die(mysqli_error($my_sqli));
$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    while ($row2 = $data2->fetch_assoc()) {
        echo $row2['id'];
    } // end child loop

} // end parent loop

?>

这是我得到的结果

1

1234

2

3

4

5

6

7

8

9

10

【问题讨论】:

  • 因为您第一次在外循环中消耗了第二个查询的所有结果集。基本上到了 EndOfFile 所以没有什么要获取的了
  • 是的,这就是它的工作原理,您需要requery。如果您想再次获取数据。或者请先将两个数据存储在数组中,然后再进行操作。

标签: php mysqli


【解决方案1】:

最简单的做法是将query2中的所有值读入一个数组,然后在循环中输出数组的内容:

$my_sqli = new mysqli('localhost', 'root', '', 'taskpro') or die(mysqli_error($my_sqli));
$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

$rows2 = $data2->fetch_all(MYSQLI_ASSOC);
while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    foreach ($rows2 as $row2) {
        echo $row2['id'];
    } // end child loop

} // end parent loop

如果由于某种原因确实需要在外循环中迭代结果集,可以使用mysqli_data_seek 重置指针:

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    while ($row2 = $data2->fetch_assoc()) {
        echo $row2['id'];
    } // end child loop
    // reset $data2 result pointer
    $data2->data_seek(0);

} // end parent loop

【讨论】:

  • 感谢您的帮助,我实际上尝试将结果读入数组(不使用 fetch_all() ),但运气不佳。感谢您对此进行更多说明:)
  • @Nick 是的,我有。它就像一个魅力。再次感谢
【解决方案2】:

基本上,在完成外部查询的第一次迭代后,您已经用尽了第二个查询的结果集。

有几种方法可以做到这一点,这里有一些建议

首先,您可以将第二个查询的所有结果加载到一个数组中,然后每次在外循环中重新处理该数组。 但是,fetch_all() 功能仅在您安装了 MYSQL Native Driver 时可用。 (MYSQLIND)

<?php
$my_sqli = new mysqli('localhost', 'root', '', 'taskpro');
if (!$my_sqli) {
    die('Connect Error: ' . mysqli_connect_errno());
}

$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

$allData2 = data2->fetch_all(MYSQLI_ASSOC);

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    foreach ( $allData2 as $row ) {
        echo $row2['id'];
    }
} // end parent loop
?>

或者您可以使用mysqli_result::data_seek() 函数将指针重置为查询结果的第一行,如下所示

<?php
$my_sqli = new mysqli('localhost', 'root', '', 'taskpro');
if (!$my_sqli) {
    die('Connect Error: ' . mysqli_connect_errno());
}

$data1 = $my_sqli->query("SELECT * FROM task_table") or die($my_sqli->error);
$data2 = $my_sqli->query("SELECT * FROM taskinfo") or die($my_sqli->error);

while ($row = $data1->fetch_assoc()) {
    echo "<br>";
    echo $row['id'];
    echo "<br>";

    $data2->data_seek(0);   // make sure the pointer is at the beginning before looping
    while ($row2 = $data2->fetch_assoc()) {
        echo $row2['id'];
    } 
}
?>

【讨论】:

    【解决方案3】:

    首先,您根本不需要while 循环。这只是让你感到困惑。你可以简单地使用foreach($data1 as $row)。话虽如此,它不会解决你的问题。

    要解决您的问题,请根据query 的结果调用fetch_all(MYSQLI_ASSOC),或者将它们简单地链接在一起。请注意,这仅适用于静态查询。如果你需要在你的 SQL 中使用变量,你应该使用prepared statements

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli('localhost', 'root', '', 'taskpro');
    $mysqli->set_charset('utf8mb4');
    
    $data1 = $mysqli->query("SELECT * FROM task_table")->fetch_all(MYSQLI_ASSOC);
    $data2 = $mysqli->query("SELECT * FROM taskinfo")->fetch_all(MYSQLI_ASSOC);
    
    foreach ($data1 as $row) {
        echo "<br>";
        echo $row['id'];
        echo "<br>";
        foreach ($data2 as $row2) {
            echo $row2['id'];
        } // end child loop
    } // end parent loop
    

    我还从您的代码中删除了手动错误检查,这只会妨碍您的代码,并且实际上不应该在您的工作代码中占有一席之地。阅读How to get the error message in MySQLi?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      相关资源
      最近更新 更多