2012-04-16 117 views
1

我遇到了一個有趣的問題,即使用一對選擇查詢和幾個連接從mysql表中檢索數據。MySQL PHP while循環 - 一個記錄比預期的要少返回

1)查詢:

$task_details = "SELECT tasks.task, "; 
$task_details = $task_details . "tasks.description,"; 
$task_details = $task_details . "tasks.finishby, "; 
$task_details = $task_details . "responsibles.full_name, "; 
$task_details = $task_details . "task_assignments.completed, "; 
$task_details = $task_details . "tasks.id, "; 
$task_details = $task_details . "responsibles.user_id "; 
$task_details = $task_details . "FROM tasks,task_assignments,responsibles "; 
$task_details = $task_details . "WHERE "; 
$task_details = $task_details . "tasks.id = task_assignments.id_task AND "; 
$task_details = $task_details . "responsibles.id = task_assignments.id_assignee AND "; 
$task_details = $task_details . "tasks.id = $id_task;"; 

$task_details_q = mysql_query($task_details) or die(mysql_error()); 

1a)中得到的示例查詢:

SELECT tasks.task, tasks.description, tasks.finishby, responsibles.full_name, task_assignments.completed, tasks.id, responsibles.user_id 
FROM tasks, task_assignments, responsibles 
WHERE tasks.id = task_assignments.id_task 
AND responsibles.id = task_assignments.id_assignee 
AND tasks.id =19 

2)HTML/PHP代碼:

<table class="task_table"> 
     <thead> 
      <th>Task</th> 
      <th>Description</th> 
      <th>Due date</th> 
      <th>Person</th> 
      <th>Completed</th> 
     </thead> 
     <?php 

     $even = false; 
     $trow = ""; 
while($row = mysql_fetch_array($task_details_q)) 
     { 

      $trow = $trow . "<tr"; 
      if($even) $trow = $trow . " style=\"background-color: #f2f2ed; \""; 
      $trow = $trow. ">"; 
      $trow = $trow . "<td >$row[0]</td>"; 
      $trow = $trow . "<td>" . $row[1] . "</td>"; 
      $trow = $trow . "<td>" . date('d-m-Y',$row[2]) . "</td>"; 
      $trow = $trow . "<td>$row[3]</td>"; 
      $trow = $trow . "<td style=\"text-align: center;\" >"; 
      if($row[4] > 0) 
      { 
       $trow = $trow . "<a href=\"javascript:modifyCompleted('remove','$row[6]',$row[5])\" title=\"Click to change completion of this task by this person\">yes</a>"; 
      } 
      else 
      { 
       $trow = $trow . "<a href=\"javascript:modifyCompleted('add','$row[6]',$row[5])\" title=\"Click to change completion of this task by this person\">no</a>"; 
      } 
      $trow = $trow . "</td>"; 
      $trow = $trow . "</tr>"; 

      $even =! $even; 
      $number = $number + 1; 
     } 
      $trow = $trow . "<tr style=\"border-top: 1px solid #666666;\"><td></td><td></td><td></td><td></td>"; 
      $trow = $trow . "<td>"; 
      $trow = $trow . "<a href=\"javascript:modifyCompleted('add_all','all',$task_details_array[5])\" title=\"Click to complete all\">Complete all</a>"; 
      echo $trow; 
     ?> 
    </table><br /> 
    <span style="text-align: center;display:block;font-size: 12px;"><a href="tasks.php">Go back to task overview</a></span> 

3)問題:出於某種原因,顯示的表總是省略一個記錄。我在PHP腳本的數量上使用了相同(或非常相似的概念),但從未遇到過同樣的問題。我認爲查詢本身不是問題 - 當我直接針對數據庫運行它時,它會返回正確數量的值......(我認爲)。

+0

僅供參考,很可能您對SQL注入敏感。您應該始終使用查詢中使用的數據。更好的做法是學習使用PDO準備好的查詢,以完全避免這個問題。 – Brad 2012-04-16 21:11:29

+1

我不確定這是否是問題的原因,但是您沒有完成最後一行。你看到源代碼中的正確結果嗎? – jeroen 2012-04-16 21:18:33

+0

@ jeroen:好眼睛,你說得對 - 最後一排沒有'關閉'。不幸的是,這並沒有解決問題。:( – TomasH 2012-04-17 20:24:15

回答

0

由於php似乎是正確的,有可能是問題的原因是在HTML中。您的標題行沒有<tr>標記,因此您可能因爲缺少第一條記錄而導致瀏覽器窒息。

解決了這個問題後,我會建議在html驗證器中檢查你的html,以確保沒有更多的錯誤。

0

@Ben:這是mysql_query($task_details)while($row = mysql_fetch_array($task_details_q))之間的完整代碼:

$task_details_q = mysql_query($task_details) or die(mysql_error()); 
$task_details_array = mysql_fetch_array($task_details_q,MYSQL_NUM); 

for($x=0;$x < sizeof($task_details_array);$x++) 
{ 
    echo $x . ". : " . $task_details_array[$x] . "<br />"; 
} 

>

<h3>Task details - "<?php echo strtoupper($task_name); ?>"</h3> 
<span class="notifierOK">Table below lists all people assigned to the task - including the status (complete/incomplete). To change person's status click on the 'yes' or 'no' link. If you then go back 
to (<a href="tasks.php">previous page</a>) the completion percentage value will be re-calculated.</span><br /> 

<form id="task_details" method="post" name="task_details" style="margin-left: auto; margin-right: auto;width: 800px;box-shadow:10px 10px 5px #888888;"> 
<table class="task_table"> 
     <thead> 
      <tr> 
      <th>Task</th> 
      <th>Description</th> 
      <th>Due date</th> 
      <th>Person</th> 
      <th>Completed</th> 
      <tr /> 
     </thead> 
     <?php 

     $even = false; 
     $trow = ""; 

     while($row = mysql_fetch_array($task_details_q,MYSQL_NUM)) 

請注意,我已經根據你的建議,增加了 'MYSQL_NUM' 作爲數組類型呢?它不一定屬於那裏。

2

2件事:

1)你不應該在你添加信息的時候提交答案。您應該點擊原始問題下的「編輯」,並在問題中添加新信息。

2)我想如果我澄清如何mysql_querymysql_fetch_array工作,你會看到發生了什麼。

當您使用「SELECT」鍵調用mysql_query時,查詢它會返回一個resource。這個resource只是對記錄集的引用。然後當你撥打mysql_fetch_array那它會返回當前記錄,並提前記錄指針。

因此,當您第一次致電mysql_query時,記錄指針指向第一個結果。然後你調用mysql_fetch_array將第一條記錄作爲數組返回,並且指針前進到第2條記錄。下次您撥打mysql_fetch_array時,會返回第二條記錄,指針將指向第三條記錄。

如果沒有第三條記錄,下次您撥打mysql_fetch_array時,將無法找到相應的記錄,並返回false。

這就是爲什麼你使用while($row = mysql_fetch_array($task_details_q,MYSQL_NUM))。您將結果放入變量$row並推進結果指針,然後使用$row執行一些操作。最終你會提示指針超過最後的結果,並且$row將是錯誤的,這將阻止你的while循環前進。

現在,我已經通過理論去這裏是做什麼用你的代碼發生的事情(我就去掉無關的代碼//...一路上添加自己的評論):

$task_details_q = mysql_query($task_details) or die(mysql_error()); 
//now you have a resource $task_details_q, it points to the first result 


$task_details_array = mysql_fetch_array($task_details_q,MYSQL_NUM); 
//you retreive the first result, and advance the pointer to the second result 

for($x=0;$x < sizeof($task_details_array);$x++) 
{ 
      //you perform operations (echo'ing in this case) on your first result 
    echo $x . ". : " . $task_details_array[$x] . "<br />"; 
} 

//... HTML CODE SKIPPED 

$even = false; 
$trow = ""; 

//the first time this while statement is called you place the data from the second result in $row, 
     //and advance the pointer to the third result 
//the next time you go through the loop you try to place the data from the third result in $row, 
     //since you say there are only 2 results to your query $row is simply false. 
     //This causes the while to stop executing and the code to continue on 
while($row = mysql_fetch_array($task_details_q,MYSQL_NUM)) 
{ 
    //... PRINT TABLE CELLS FROM $row SKIPPED 
} 

//... REMAINING HTML SKIPPED 

我不確定如果您確實需要代碼塊:

$task_details_array = mysql_fetch_array($task_details_q,MYSQL_NUM); 
for($x=0;$x < sizeof($task_details_array);$x++) 
{ 
    echo $x . ". : " . $task_details_array[$x] . "<br />"; 
} 

或者您是否只是爲了調試而添加它。如果它只是用於調試,請將其刪除,並且您的第一個結果將顯示在while循環中。如果您需要執行for循環,請評論此答案,然後編輯我的答案以使用forwhile循環中的第一個結果。

+0

首先,感謝您的回覆 - 只是注意到了它。無論如何;是的 - FOR循環僅用於調試。因爲查詢結果在實際的'while'循環之前放入一個數組中,第一次在'while'循環內調用時,指針已經在位置[1]而不是[0] ...我已經移動了$'task_details_array = mysql_fetch_array($ task_details_q,MYSQL_NUM);''while'循環下面,它的功能就像一個魅力!非常感謝和THUMBS UP! – TomasH 2012-04-23 21:12:07

+0

@TomasH如果我回答你的問題,請接受我的回答。另外,如果你清理了這個問題,那將會很棒:把你輸入的額外信息作爲答案,並將它們編輯到原始問題中並刪除答案。 – ben 2012-04-24 04:53:29

0

我解決了它,我有同樣的問題。

$run_query = mysqli_query($conn, $stores); 

       if ($run_query === false){ 
        //error 
       }else if (mysqli_num_rows($run_query)){ 
        $row = mysqli_fetch_array($run_query); 
        echo 'bla bla bla' //on this echo I needed to show the data once. 
        $run_query = null; 
        $run_query = mysqli_query($conn, $stores); 
        while ($row = mysqli_fetch_array($run_query)) { //and here I needed to show up the loops of the results of my query.} 

所以...我只是重置運行查詢的變量並重新運行搜索。它爲我工作! ;)