嵌套while循环中的SQL语句

时间:2016-09-09 14:06:51

标签: php sql-server

我正在为我们的IT部门写一份股票申请,而且我对自己走的路是最好的。

我创建了一个'产品组'桌子和产品'与ID(一个产品组到多个产品)产品组链接的表格,例如LaserJet Pro 400和产品将是单个消耗品..黑色,品红色,青色等。

所以发生的事情是我有一个while循环用于显示组,然后是一个嵌套的while循环用于显示该组中的产品。

我担心的是它是在很快发生的很多sql语句,在这个早期阶段似乎没有性能问题,但我不确定......这是可以接受的吗?有更好的方法吗?

foreach ($_POST['BeginLocation'] as $key => $value) {$LocationID = $key;}

echo '<div class="nmform"><form name="StockTake" action="index.php" method="post" enctype="multipart/form-data">';

include "../DBCon/RDPNearMisses.php";

$GetProductGroups = sqlsrv_query($NMDB, "select distinct PD.ProductGroupID, PG.GroupName
                                        from [JobObservations].[dbo].[ITStk.Products] as PD
                                        inner join [JobObservations].[dbo].[ITStk.ProductGroups] as PG on PD.ProductGroupID = PG.ProductGroupID
                                        where PD.LocationID = $LocationID");

                       if( $GetProductGroups === false ) {
                           if( ($errors = sqlsrv_errors() ) != null) {
                               foreach( $errors as $error ) {
                                   echo "SQLSTATE: ".$error[ 'SQLSTATE']."<br />";
                                   echo "code: ".$error[ 'code']."<br />";
                                   echo "message: ".$error[ 'message']."<br />";
                               }
                           }
                       }

                       while ($row = sqlsrv_fetch_array($GetProductGroups)) {echo '<h4>'.$row['GroupName'].'</h4>';
                                                $ProductGroupID = $row['ProductGroupID'];

                                                $GetProducts = sqlsrv_query($NMDB, "select PD.ProductID, PD.ProductGroupID, PD.ProductCode, PD.ProductDescription
                                                from [JobObservations].[dbo].[ITStk.Products] as PD
                                                inner join [JobObservations].[dbo].[ITStk.ProductGroups] as PG on PD.ProductGroupID = PG.ProductGroupID
                                                inner join [JobObservations].[dbo].[ITStk.Locations] as LC on PD.LocationID = LC.LocationID
                                                where PD.LocationID = $LocationID
                                                and PD.ProductGroupID = $ProductGroupID
                                                order by LC.LocationDescription asc, PG.GroupName asc, PD.ProductCode asc");

                                                if( $GetProducts === false ) {
                                                    if( ($errors = sqlsrv_errors() ) != null) {
                                                        foreach( $errors as $error ) {
                                                            echo "SQLSTATE: ".$error[ 'SQLSTATE']."<br />";
                                                            echo "code: ".$error[ 'code']."<br />";
                                                            echo "message: ".$error[ 'message']."<br />";
                                                        }
                                                    }
                                                }
                                                echo '<table><th>Code</th><th>Description</th><th>Qty</th>';
                                                while ($row1= sqlsrv_fetch_array($GetProducts)) {echo '<tr><td>'.$row1['ProductCode'].'</td><td>'.$row1['ProductDescription'].'</td><td><select name="'.$row1['ProductID'].'"><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option></select></td></tr>';}
                                                echo '</table>';


                       }
                       echo '<input type="Submit" name="SubmitStock"></form>';
                       sqlsrv_close($NMDB);
         echo '</div>';

1 个答案:

答案 0 :(得分:1)

虽然您的数据很小且每个位置的组数量很少,但您可能不会注意到差异,但随着每个位置的组数发生变化,您可能需要考虑切换到1个查询和while循环:

SELECT DISTINCT
    PD.ProductID,
    PG.GroupName,
    PD.ProductGroupID,  
    PD.ProductCode,
    PD.ProductDescription
FROM [JobObservations].[dbo].[ITStk.Products] AS PD
INNER JOIN [JobObservations].[dbo].[ITStk.ProductGroups] AS PG ON PD.ProductGroupID = PG.ProductGroupID
INNER JOIN [JobObservations].[dbo].[ITStk.Locations] AS LC ON PD.LocationID = LC.LocationID
WHERE PD.LocationID = $LOCATIONID;

运行良好,因为它会为您提供包含未使用的GroupName以及您在表中使用的产品ID和产品描述的记录集。

此外,除非加入表ITStk.Locations仅限于LocationID实际位于Locations表中的记录,否则无需在此处加入。您不使用任何字段来限制结果集或SELECT。

几乎在您发现自己抓取记录集的任何时候,在读取/循环记录集时,您发出更多SQL,您可以将其转换为单个SQL语句。

要将GroupName作为标题放在你的表格中,在你的1 while循环中你可以做类似下面的事情(原谅我,自从我写PHP以来已经过了几年):

$GetProductGroups = sqlsrv_query($NMDB, "SELECT DISTINCT
                                        PD.ProductID,
                                        PG.GroupName,
                                        PD.ProductGroupID,  
                                        PD.ProductCode,
                                        PD.ProductDescription
                                    FROM [JobObservations].[dbo].[ITStk.Products] AS PD
                                    INNER JOIN [JobObservations].[dbo].[ITStk.ProductGroups] AS PG ON PD.ProductGroupID = PG.ProductGroupID
                                    INNER JOIN [JobObservations].[dbo].[ITStk.Locations] AS LC ON PD.LocationID = LC.LocationID
                                    WHERE PD.LocationID = $LOCATIONID
                                    ORDER BY GroupName;");

if( $GetProductGroups === false ) {
   if( ($errors = sqlsrv_errors() ) != null) {
       foreach( $errors as $error ) {
           echo "SQLSTATE: ".$error[ 'SQLSTATE']."<br />";
           echo "code: ".$error[ 'code']."<br />";
           echo "message: ".$error[ 'message']."<br />";
       }
   }
}

while ($row = sqlsrv_fetch_array($GetProductGroups)) {

    /*If the groupname of the current record is different then the last record's group name (notice order by on query) then echo out the header and start a new table*/
    if ( $groupname != $row['GroupName']) {
        echo '<h4>'.$row['GroupName'].'</h4>';
        echo '<table><th>Code</th><th>Description</th><th>Qty</th>';
    }

    /*echo out the row into the table*/
    echo '<tr><td>'.$row['ProductCode'].'</td><td>'.$row['ProductDescription'].'</td><td><select name="'.$row1['ProductID'].'"><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option><option>0</option></select></td></tr>';


    /*again if we started a new table because the groupname is new in the recordset, then close the table*/
    if ( $groupname != $row['GroupName']) {         
        echo '</table>';
    }
    /*Capture group name for future iterations*/    
    $groupname = $row['GroupName'];

}

echo '<input type="Submit" name="SubmitStock"></form>';
sqlsrv_close($NMDB);
echo '</div>';