2016-01-20 62 views
1

後,我有一個選擇,我有3個結果:更新行的MySQL選擇的foreach

$stmt = $handler->prepare("SELECT id,comments,likes,views FROM sites WHERE usr_id = '$usr_id'"); 
$stmt->execute(); 

在此之後選擇我有3個結果。現在,我想在另一個表更新或插入新行對於每個結果

這是我的完整代碼

我沒有在表中的任何更新或新的插入。任何人都可以幫我嗎?

$stmt = $handler->prepare("SELECT id,comments,likes,views FROM sites WHERE usr_id = '$usr_id'"); 
    $stmt->execute(); 
    while($row = $stmt->fetch(PDO::FETCH_ASSOC)){ 
    $rows[]=$row; 
    foreach($rows as $row){ 
    $site_id = $row[id];  

      $stmt = $handler->prepare("SELECT id FROM session WHERE site_id = '$site_id' AND usr_id = '$usr_id'"); 
      $stmt->execute(); 
      $no=$stmt->rowCount(); 

      if ($no > 0) 
      { 
       $stmt = $handler->prepare("UPDATE session SET comments = '$comments' , likes = '$likes' , views = '$views' WHERE usr_id = $usr_id AND site_id = $site_id"); 
       $stmt->execute(); 

      } 
      else 
      { 
       $stmt = $handler->prepare("INSERT INTO session(user_id,site_id,comments,likes,views)VALUES('$user_id','$site_id','$comments','$likes','$views')"); 
       $stmt->execute(); 

      } 
     } 
    } 
+1

爲什麼'foreach($ rows as $ row){''while'循環;使用'fetchAll'?您也可以不安全地使用準備好的語句,對它們進行參數化。 – chris85

+2

[您的腳本存在SQL注入攻擊的風險。](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)瞭解[prepared](http: //en.wikipedia.org/wiki/Prepared_statement)[PDO]聲明(http://php.net/manual/en/pdo.prepared-statements.php)和[MySQLi](http://php.net) /manual/en/mysqli.quickstart.prepared-statements.php)並考慮使用PDO,[這真的很簡單](http://jayblanchard.net/demystifying_php_pdo.html)。 –

+0

你也可以使用'insert on duplicate update'。 http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html – chris85

回答

0

@ Miken32的回答將是理想的方式。

直接固定到您的代碼將是這個樣子:

$stmt1 = $handler->prepare("SELECT id,comments,likes,views FROM sites WHERE usr_id = :usr_id"); 
$stmt1->bindValue(':usr_id', $usr_id); 
$stmt1->execute(); 
while ($row = $stmt1->fetch(PDO::FETCH_ASSOC)) { 
    $stmt2 = $handler->prepare("SELECT id FROM session WHERE site_id = :site_id AND usr_id = :usr_id"); 
    $stmt2->bindValue(':usr_id', $usr_id); 
    $stmt2->bindValue(':site_id', $row['id']); 
    $stmt2->execute(); 

    if ($stmt2->rowCount() > 0) { 
     $stmt3 = $handler->prepare("UPDATE session SET comments = :comments , likes = :likes , views = :views WHERE usr_id = :usr_id AND site_id = :site_id"); 
    } else { 
     $stmt3 = $handler->prepare("INSERT INTO session(user_id,site_id,comments,likes,views)VALUES(:usr_id,:site_id,:comments,:likes,:views)"); 
    } 
    $stmt3->bindValue(':comments', $row['comments']); 
    $stmt3->bindValue(':likes', $row['likes']); 
    $stmt3->bindValue(':views', $row['views']); 
    $stmt3->bindValue(':usr_id', $usr_id); 
    $stmt3->bindValue(':site_id', $row['id']); 
    $stmt3->execute(); 
} 

但是,這不是去它的最好方式。 INSERT ...UPDATE ON DUPLICATE KEY會更好。

+0

好的謝謝你的解決方案...... @梅達 現在我必須在表會話 問題是... 一個INSERT當我做回聲後 而($行= $ stmt1->取(PDO :: FETCH_ASSOC)){ 那麼結果是53,54,55 但在表會話中,我只有一個條目爲ID 53. 任何人都可以解決這個問題 –

1

第一個問題,你沒有充分利用準備好的語句。使用參數(查詢中的?),然後用​​調用中的值填充它們。

另外,在循環外準備你的查詢,並在裏面執行它。這是事先準備報表的關鍵優勢之一,只需準備一次就可以減少開銷。

最後,在查詢之前不需要檢查數據庫,然後執行兩個查詢之一。讓MySQL檢查數值是否已經以INSERT...ON DUPLICATE KEY UPDATE的語法存在。這依賴於正確設置的數據庫,因此在(session.usr_id, session.site_id)上應該有UNIQUE索引。

這是未經測試,但應該讓你去:

$stmt1 = $handler->prepare("SELECT id,comments,likes,views FROM sites WHERE usr_id = ?"); 
$stmt2 = $handler->prepare("INSERT INTO session SET comments = ?, likes = ?, views = ?, usr_id = ?, site_id = ? ON DUPLICATE KEY UPDATE comments = VALUES(comments), likes = VALUES(likes), views = VALUES(views)"); 

$stmt1->execute(array($usr_id)); 
while($row = $stmt1->fetch(PDO::FETCH_ASSOC)) { 
    $site_id = $row["id"]; 
    $stmt2->execute(array($comments, $likes, $views, $usr_id, $site_id)); 
} 
+0

中取出PHP感謝您的代碼。 不工作。 當我在$ site_id = $ row [「id」]; 我看不到結果。 在phpmyadmin當我做查詢我有3個結果 –

+0

這是基本的調試。確保'$ usr_id'有一個值,檢查以確保'$ stmt1'和'$ stmt2'是有效的,檢查execute()的返回等等...... – miken32