【问题标题】:nested while loop stops after first iteration PHP嵌套的while循环在第一次迭代PHP后停止
【发布时间】:2021-05-27 07:11:50
【问题描述】:

我对此很陌生,所以我可能缺少一些非常基本的东西,但我正在尝试编写一些 PHP 脚本。我想规范化我的主数据表,这是关于二手车、品牌、型号、价格等的信息。所以我有另一个表,其中包含所有独特的汽车制造商,它存储 makeName 和唯一的 id @ 987654324@ 在我的脚本中,我连接到数据库,从主表中读取所有数据,将其作为 SQL 查询运行,然后将其存储为变量。我对make 表也这样做。

然后我尝试运行一个嵌套的 while 循环,将主表中 Manufacturer 列中的所有字符串替换为 make 表中的 makeId,以便我可以链接这两个表。它适用于一次迭代然后停止,我尝试在任一和两个while循环中的fetch_assoc之后添加!==FALSE,但这给了我我认为的无限循环。这是我的代码...

<?php

include("conn.php");

$sqlAll= "SELECT * FROM carData";

$carDataResult = $conn->query($sqlAll);

if(!$carDataResult){
    echo $conn->error;
    die();
}

$sqlMake = "SELECT * FROM 000make";
$makeResult = $conn->query($sqlMake);  

if(!$makeResult){
    echo $conn->error;
    die();
}  

while ( $make =$makeResult-> fetch_assoc()){

    $makeID = $make['makeId'];
    $makeName = $make['makeName'];

    while ($row = $carDataResult->fetch_assoc()){
    
        $sqlUpdate="UPDATE carData SET Manufacturer = '$makeID'
           WHERE Manufacturer='$makeName' AND Manufacturer IS NOT NULL";
        
        $res = $conn->query($sqlUpdate);
 
        if(!$res){
            echo $conn->error;
            die();
        }
    }
}

?>

【问题讨论】:

  • 看起来$carDataResult-&gt;fetch_assoc()只有一行或者die()执行尝试运行print_r($carDataResult-&gt;fetch_assoc())并确保你有超过1行,如果只有一行那么逻辑是正确。
  • 如果你想多次遍历同一个mysqli结果集,你需要在下一个循环之前重置内部指针,使用mysql::data_seek()

标签: php mysql loops while-loop nested


【解决方案1】:

作为一般规则,读取结果集并循环遍历它以运行连续查询是处理此类问题的错误方法。您可以在一个查询中完成所有操作:

update carData set `Manufacturer` = (select `makeId` from `000make` where 000make.makeName=carData.Manufacturer) 

你的整个程序变成:

<?php

include("conn.php");

$sqlAll= "update carData set `Manufacturer` = (select `makeId` from `000make` where 000make.makeName=models.Manufacturer) ";

$carDataResult = $conn->query($sqlAll);

if(!$carDataResult){
    echo $conn->error;
    die();
} else {
    echo "Update Successful"
}

顺便说一句,我会在您的carData 表中创建一个新列(可能称为makeId)并将数据插入其中,而不是覆盖Manufacturer 列。这样,如果出现问题,您可以保留制造商列。您可以稍后删除该列。

【讨论】:

  • 我发布问题后大约 10 分钟,在盯着这个问题看了一整天之后,我意识到我根本不需要嵌套循环并写了这个,这很笨重并且解决了问题,但是我更喜欢你的解决方案#TangentiallyPerpendicular...
  • 为了使其有效,select makeId from 000make where 000make.makeName=models.Manufacturer 必须有意义。但很明显,事实并非如此。正确的想法。
  • @strawberry 你会详细说明“显然不是”。无论你在说什么,我都不明白。
  • @TangentiallyPerpendicular,这行得通,我只需将models.Manufacturer更改为carData.Manufacturer,因为我的主表称为carData,但除此之外,它运行良好,谢谢。
  • 我的错 - 我抄错了表名?‍♂️。希望你发现它仍然有用。
【解决方案2】:

在我发布问题后大约 10 分钟,在盯着这个问题看了一整天后,我意识到我根本不需要嵌套循环并写了下面的代码,虽然很笨重,但它解决了问题,但我喜欢您的解决方案更好@TangentiallyPerpendicular...感谢您的帮助...

while ($make =$makeResult-> fetch_assoc()){

     $makeID = $make['makeId'];
     $makeName = $make['makeName'];

      $sqlUpdate="UPDATE carData SET Manufacturer = '$makeID'
      WHERE Manufacturer='$makeName' AND Manufacturer IS NOT NULL";
        
      $res = $conn->query($sqlUpdate);
 
      if(!$res){
          echo $conn->error;
          die();
      }
 }

【讨论】: