簡體   English   中英

如何使用單個MySQL查詢更新表中的多個記錄?

[英]How do I update multiple records in a table with a single MySQL query?

我想使用一個查詢來更新MySQL表中的多個記錄。 基本上,這是一個任務表,其中包含在不同日期為不同人員分配的任務。 當這些作業被更改並通過在線表單提交時,將提交許多POST數據(幾乎所有待處理的作業)。 我已經編寫了一種算法,可以對所有這些信息進行排序,並從中獲得想要的信息,但是我一直堅持編寫查詢以更新MySQL表:

  // Find the modified records and save their information
  $update = 0;
  for ( $n = 0; $n < $total_records; $n++ )
  {
     if ( $_POST['update'.$n] == true )
     {
        $updates_arr[$update] = array( intval($_POST['user_id'.$n]), intval($_POST['task'.$n]), $_POST['date'.$n] );
        $update++;
     }
  }

  if ( $mysql_db = OpenDatabase() )
  {
     $query  = "UPDATE tasks_tbl";
     if ( $updates_arr[0] )
     {
        $query .= "   SET task = ".$updates_arr[0][1]." WHERE user_id = ".$updates_arr[0][0]." AND date = ".$updates_arr[0][2];
     }

     for ( $n = 1; $n < $updates; $n++ )
     {
        $query .= ",   SET task = ".$updates_arr[$n][1]." WHERE user_id = ".$updates_arr[$n][0]." AND date = ".$updates_arr[$n][2];
     }

     $result = mysql_query( $query, $mysql_db );

     if ( $result )
     {
        $page .= "<p>Success!</p>\n\n";
     }
     else
     {
        $page .= "<p>Error: ".mysql_error()."</p>\n\n";
     }
  }

這是生成的查詢:

UPDATE tasks_tbl 
   SET task = 1 
 WHERE user_id = 16 
   AND date = 2010-05-05,  
   SET task = 1 
 WHERE user_id = 17 
   AND date = 2222-02-22

任何建議,將不勝感激。 謝謝。

您可以生成如下查詢:

UPDATE tasks_tbl SET task=1 WHERE 
    (user_id=16 AND date='2010-05-05') OR
    (user_id=17 AND date='2010-02-22')

有一些技巧可以避免使用(... and ...) or (... and ...)構造(連接字段和參數: "concat(user_id, date) = '". $user_id. $date. "'" ,但它們的工作速度稍慢。

PHP代碼:

for ($i = 0; !empty($_POST['update'. $i]; $i++)
    if (intval($_POST['task'.$i]) == 1)
        $cond[] = '(user_id='. intval($_POST['user_id'. $i]).
        ' and date=\''. mysql_real_escape_string($_POST['date'.$i]). '\')';

$query = 'UPDATE tasks_tbl SET task=1 WHERE '. implode(' OR ', $cond). ')';

編輯:我不太明白為什么您需要在單個查詢中執行此操作。 task可以有多少個值? 1、2、3或更多? 具有3個值,可以使用嵌套的IF(...)函數:

UPDATE tasks_tbl SET task=if('. <imploded tasks with value 1>. ', 1, if('.
<tasks with value 2>. ', 2, if('. <tasks with 3>. ', 3,
task))) /* leave as is otherwise */

或者您可以在我提供的代碼上添加一個簡單的循環:

for ($j = 1; $j <= 3; $j++)
    for ($i = 0; !empty($_POST['update'. $i]; $i++)
        if (intval($_POST['task'.$i]) == 1)
            $cond[] = '(user_id='. intval($_POST['user_id'. $i]).
            ' and date=\''. mysql_real_escape_string($_POST['date'.$i]). '\')';

    mysql_query('UPDATE tasks_tbl SET task=1 WHERE '. implode(' OR ', $cond). ')');

我在這里不同意您的體系結構,但是以下方法應該可行。 使用風險自負:

UPDATE
     Tasks_Table
SET
     task =
          CASE
               WHEN user_id = 16 AND date = 2010-05-05 THEN 1
               WHEN user_id = 17 AND date = 2222-02-22 THEN 1
               ...
          END
WHERE
     (user_id = 16 AND date = 2010-05-05) OR
     (user_id = 17 AND date = 2222-02-22) OR
     ...

在您的示例中,所有情況下的task = 1,但是使用CASE語句可以將它們更改為每種情況所需的值。 我將弦樂建設留給您。

我希望使用准備好的查詢並在數據上循環(如果需要,在事務內)。 這使它更易於理解,對於維護性更好。

您的代碼也帶有sql注入不安全的味道,這種情況可以消除准備查詢。

參見: http : //www.php.net/manual/en/mysqli.prepare.php或使用PDO prepare更好的方法:

謝謝大家的建議。 我最終進行了多次查詢,因為這樣做顯然不像我希望的那樣簡單。

    foreach ( $updates_arr as $record => $data ):
       $query  = "UPDATE tasks_tbl";
       $query .= "   SET task = ".$data[1];
       $query .= "   WHERE task_id = ".$data[0];
       $result = mysql_query( $query, $mysql_db );
       if ( !$result )
       {
          break;
       }
       endforeach;

您在尋找這個嗎?

UPDATE tasks_tbl 
   SET task = 1 
 WHERE (user_id = 16 AND date = 2010-05-05) 
       OR (user_id = 17 AND date = 2222-02-22)

或者您正在嘗試使用單個語句將“任務”設置為不同行中的不同值? 后者是不可能的

我認為只有一種說法是不可能的。 您將需要創建單獨的UPDATE語句:

UPDATE tasks_tbl SET task = 1 WHERE user_id = 16 AND date = 2010-05-05;
UPDATE tasks_tbl SET task = 1 WHERE user_id = 17 AND date = 2222-02-22

您可以將它們作為一個以';'分隔的字符串傳遞到mysql_query()中。 如果您將mysql設置為接受多個查詢

似乎支持多個查詢。 您只需要傳遞標志65536作為mysql_connect的5個參數(client_flags)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM