1

I'm upgrading all my mysql_* to PDO. I can handle simple SELECTs and INSERTs. But I have one complex SELECT using nested loops that I am making a dog's dinner of. I'll post the mysql_* code, which outputs a two-column table with total registrations at A1 level in the first column and total registrations at A1 level who have paid in brackets in the second column.

-------------------------
Smithsville : A1 |      |
  10             | (7)  |
-------------------------
Grange : A1      |      |
   4             |  (4) |
-------------------------
Beau Ridge : A1  |      |
   23            |  (16)|
-------------------------
Jonesboro : A1   |      |
   9             | (9)  |
-------------------------
Lexing : A1      |      |
  3              | (1)  |
-------------------------

In the full application further tables are genertated across the page for the other levels.

$levels = array('A1', 'A2', 'B1', 'B2');

$centres = array('Smithsville', 'Grange', 'Plateau Ridge', 'Jonesboro', 'Lexing');

for ($j = 0; $j < 1; $j++)  /* Does not loop; selects only A1 in queries below*/
    {
       for ($k=0; $k<5; $k++) /* Cycles through the centres */
         {
        $show_count = mysql_query("SELECT COUNT(Centre) 
                                          FROM exam 
                    WHERE exam.Centre='".$centres[$k]."' 
                    AND exam.Level='".$levels[$j]."'");

        $show_paid = mysql_query("SELECT COUNT(Centre) 
                       FROM exam
                       JOIN personal 
                       ON exam.P_ID=personal.P_ID
                       WHERE personal.Paid='1' 
                       AND exam.Centre='".$centres[$k]."'
                       AND exam.Level='".$levels[$j]."'");


    $result_rows = mysql_num_rows($show_count);

    $result_rows2 = mysql_num_rows($show_paid);

        if ($result_rows == 0) 
           { echo 'No registrations';}

              if ($result_rows2 == 0) 
           { echo 'No payments';}


        echo '<table class="Font3White">
            <tr class="Title">
              <td class="width8">'.$centres[$k].' : '.$levels[$j].'</td>
            <tr>';
while (($row = mysql_fetch_row($show_count)) && ($row2 = mysql_fetch_row($show_paid)))
          { 
             foreach ($row as $key => $value)  
            {
              echo '<td>';
              echo $value;  
                   echo '</td>';
            }

             foreach ($row2 as $key2 => $value2)
            {
                   echo '<td> (';
              echo $value2;  
              echo ')</td>';
            }

             echo '</tr>';
              }
        echo '</table>';
            }

        }

My PDO attempt is

    for ($j = 0; $j < 1; $j++)  /* Does not loop; selects only A1 */
            {
                        for ($k=0; $k<5; $k++) /* Cycles through the centres */
                    {

            /*//////////////////////////*/
            /*   Prepares statements    */
            /*//////////////////////////*/

        $stmt1 = $db->query("SELECT COUNT(Centre) 
                FROM exam 
                WHERE exam.Centre=:centre   
                AND exam.Level=:level");

        $stmt2 = $db->query("SELECT COUNT(Centre) 
                FROM exam
                JOIN personal 
                ON exam.P_ID=personal.P_ID
                     WHERE personal.Paid='1' 
                AND exam.Centre=:centre 
                AND exam.Level=:level");

        /*/////////////////////*/
        /*   Binds parameters  */
        /*/////////////////////*/

    $stmt1->bindParam(':centre', $centre, PDO::PARAM_STR);
    $stmt1->bindParam(':level', $level, PDO::PARAM_STR);

    $stmt2->bindParam(':centre', $centre, PDO::PARAM_STR);
    $stmt2->bindParam(':level', $level, PDO::PARAM_STR);



    /*//////////////////////////*/
    /*   Executes statements    */
    /*//////////////////////////*/

    $stmt1->execute(array($centre, $level));
    $stmt2->execute(array($centre, $level));


    echo '<table class="Font3White">
            <tr class="Title">
              <td class="width8">'.$centres[$k].' > '.$levels[$j].'</td>
            <tr>';
   while (($row = $stmt1->fetch(PDO::FETCH_ASSOC)) && ($row2 = $stmt2->fetch(PDO::FETCH_ASSOC)))
        { 
           foreach ($row as $key => $value)  
                {
                  echo '<td>';
                  echo $value;  
                       echo '</td>';
                }

                 foreach ($row2 as $key2 => $value2)
                {
                       echo '<td> (';
                  echo $value2;  
                  echo ')</td>';
                }
                echo '</tr>';
        }
    echo '</table>';
        }

    }

I know this is terrible but I hope it can be worked with.

4

2 回答 2

1

我知道让你做肮脏的工作是错误的,但就是这样。

我对您的代码进行了一些更改,因此我的代码与您的代码进行比较。

希望它可以帮助你。

$levels = array('A1', 'A2', 'B1', 'B2');

$centres = array('Smithsville', 'Grange', 'Plateau Ridge', 'Jonesboro', 'Lexing');

foreach ($levels as $level) {
    foreach ($centres as $centre) {

        // As you said, PREPARE
        $stmt1 = $db->prepare("SELECT COUNT(Centre) 
                FROM exam 
                WHERE exam.Centre=:centre   
                AND exam.Level=:level");

        $stmt2 = $db->prepare("SELECT COUNT(Centre) 
                FROM exam
                JOIN personal 
                ON exam.P_ID=personal.P_ID
                     WHERE personal.Paid='1' 
                AND exam.Centre=:centre 
                AND exam.Level=:level");

        $stmt1->bindParam(':centre', $centre, PDO::PARAM_STR);
        $stmt1->bindParam(':level', $level, PDO::PARAM_STR);

        $stmt2->bindParam(':centre', $centre, PDO::PARAM_STR);
        $stmt2->bindParam(':level', $level, PDO::PARAM_STR);

        //You don't need to pass parameters here just on PDOStatement::bindParam
        $stmt1->execute();
        $stmt2->execute();

        echo '<table class="Font3White">
            <tr class="Title">
              <td class="width8">' . $centre . ' > ' . $level . '</td>
            <tr>';

        // Fetch stuffs
        $row = $stmt1->fetch(PDO::FETCH_ASSOC);
        $row2 = $stmt2->fetch(PDO::FETCH_ASSOC);

        // Don't use while with PDOStatement::fetch, use fetchAll then foreach it.
        if ($row && $row2) {

            foreach ($row as $key /* <= Do you need it? */ => $value) {
                echo '<td>';
                echo $value;
                echo '</td>';
            }

            foreach ($row2 as $key2 /*  <= Do you need it? */ => $value2) {
                echo '<td> (';
                echo $value2;
                echo ')</td>';
            }

            echo '</tr>';
        }
        echo '</table>';
    }
}
于 2013-04-30T16:12:15.783 回答
0
  1. 你能告诉我们你是如何设置 $centre 和 $level 变量的吗?也许它们是数组,而不是字符串?如果是 - 您可能必须创建新变量并将数组中的值分配给它。像这样:

    $value_to_bind = $centres[$k];

  2. 如果您之前使用过 bindParam(),则 Execute 不需要参数。

  3. 我从未尝试使用相同的参数名称和绑定到它们的相同变量运行 2 个查询。也许这是一个问题?

于 2013-04-30T15:47:58.443 回答