准备好的语句通过记录集迭代

时间:2016-01-22 21:31:12

标签: php mysql loops mysqli

我有两个表:ContractClusterContractClusterID作为主键)和ContractContractID作为主键,ContractClusterID as外键)。我试图遍历返回的ContractClusterID记录集,并返回所有ContractID与表中相应的ContractClusterID外键。出于某种原因,我无法让它发挥作用。我只收到第一行的数据。任何帮助将不胜感激。

$PoolID = $_POST['PoolID'];
$query = "SELECT ContractCluster.ContractClusterID,ContractCluster.PoolID FROM ContractCluster WHERE ContractCluster.PoolID=?";
$stmt = $db->prepare($query);
$stmt->bind_param('s', $PoolID);
$stmt->execute();
$stmt->store_result();
$numrows = $stmt->num_rows;
$stmt->bind_result($ContractClusterID, $PoolID);

for ($i = 0; $i < $numrows; $i++) {
    $stmt->fetch();

   echo "<p>Rows Returned (ClusterID):$numrows</p>";
echo "Contract Cluster ID:  $ContractClusterID, Pool ID: $PoolID</br></br>";

    $ContractClusterID = $ContractClusterID;
    $query = "SELECT Contract.ContractID FROM Contract WHERE Contract.ContractClusterID=? ";
    $stmt = $db->prepare($query);
    $stmt->bind_param('s', $ContractClusterID);
    $stmt->execute();
    $stmt->store_result();
    $numrows = $stmt->num_rows;
    $stmt->bind_result($ContractID);
    echo "<p>Rows Returned (ContractID): '.$numrows.'</p>";
        for ($i = 0; $i < $numrows; $i++) {
            $stmt->fetch();
            echo "Contract ID: $ContractID </br>";
        };
 };

1 个答案:

答案 0 :(得分:2)

你的问题是你正在重复使用像$i这样的变量,这会弄乱你的循环。

在循环外准备查询并在内部执行也是一个好主意。这可以防止大量开销,并且是预处理语句的主要优点之一。

如果您想让自己的生活更轻松,我强烈建议您使用PDO并避免使用bind_param()bind_result()。它还允许您一次将整个结果集转储到数组中,而不是弄乱fetch()for循环。这是未经测试的,但应该给你一个开始。

$PoolID = $_POST['PoolID'];

$query1 = "SELECT ContractCluster.ContractClusterID,ContractCluster.PoolID FROM ContractCluster WHERE ContractCluster.PoolID=?";
$query2 = "SELECT Contract.ContractID FROM Contract WHERE Contract.ContractClusterID=?";
$stmt1 = $db->prepare($query1);
$stmt2 = $db->prepare($query2);

$stmt1->execute(array($PoolID));
$rows1 = $stmt1->fetchAll(PDO::FETCH_ASSOC);
$numrows1 = count($rows1);
foreach ($rows1 as $row1) {
    echo "<p>Rows Returned (ClusterID):$numrows1</p>";
    echo "Contract Cluster ID: $row1[ContractClusterID], Pool ID: $row1[PoolID]</br></br>";
    $stmt2->execute(array($row1["ContractClusterID"]));
    $rows2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
    $numrows2 = count($rows2);
    echo "<p>Rows Returned (ContractID): $numrows2</p>";
    foreach ($rows2 as $row2) {
        echo "Contract ID: $row2[ContractID] </br>";
    }
 }

如果您坚持使用MySQLi,只需在现有代码的内部循环中更改变量$i$numrows$stmt即可。但是你的代码仍然会非常低效;至少将声明准备移出循环。

所有这一切,如果无法通过加入完成,也值得一提:

SELECT cc.ContractClusterID, cc.PoolID, c.ContractID
FROM ContractCluster cc
LEFT JOIN Contract c
    USING (ContractClusterID)
WHERE cc.PoolID = ?