简体   繁体   English

如何使用单个MySQL查询更新表中的多个记录?

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

I would like to update multiple records in a MySQL table using a single query. 我想使用一个查询来更新MySQL表中的多个记录。 Basically, this is a tasks table, which has assignments for different people on different dates. 基本上,这是一个任务表,其中包含在不同日期为不同人员分配的任务。 When these assignments are changed and submitted via the Online form there is a lot of POST data that gets submitted (pretty much all the pending assignments). 当这些作业被更改并通过在线表单提交时,将提交许多POST数据(几乎所有待处理的作业)。 I've written an algorithm that sorts through all this information and gets what I want out of it, but I'm stuck on writing the query to update the MySQL table: 我已经编写了一种算法,可以对所有这些信息进行排序,并从中获得想要的信息,但是我一直坚持编写查询以更新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";
     }
  }

This is the query that is generated: 这是生成的查询:

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

Any suggestions would be appreciated. 任何建议,将不胜感激。 Thanks. 谢谢。

You can generate a query like this: 您可以生成如下查询:

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

There are hacks to avoid using (... and ...) or (... and ...) constructs (concatenate fields and params: "concat(user_id, date) = '". $user_id. $date. "'" , but they work a bit slower. 有一些技巧可以避免使用(... and ...) or (... and ...)构造(连接字段和参数: "concat(user_id, date) = '". $user_id. $date. "'" ,但它们的工作速度稍慢。

The PHP code: 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). ')';

Edit: I don't quite understand why you need to do that in a single query. 编辑:我不太明白为什么您需要在单个查询中执行此操作。 How many values task can have? task可以有多少个值? 1, 2, 3, or many more? 1、2、3或更多? With 3 values, you can use nested IF(...) functions: 具有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 */

Or you may put a simple loop on the code I've given: 或者您可以在我提供的代码上添加一个简单的循环:

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). ')');

I disagree with your architecture here, but the following should work. 我在这里不同意您的体系结构,但是以下方法应该可行。 Use at your own risk: 使用风险自负:

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
     ...

In your example you have task = 1 in all cases, but with the CASE statement you can change them to be what you need for each case. 在您的示例中,所有情况下的task = 1,但是使用CASE语句可以将它们更改为每种情况所需的值。 I'll leave the string building to you. 我将弦乐建设留给您。

I would prefer to use a prepared query and loop over the data (inside a transaction if needed). 我希望使用准备好的查询并在数据上循环(如果需要,在事务内)。 That makes it simpler to understand, which is better for maintainability. 这使它更易于理解,对于维护性更好。

Your code smells of sql injection insecurity, too, which prepared queries would eliminate. 您的代码也带有sql注入不安全的味道,这种情况可以消除准备查询。

See: http://www.php.net/manual/en/mysqli.prepare.php or even better with PDO prepare : 参见: http : //www.php.net/manual/en/mysqli.prepare.php或使用PDO prepare更好的方法:

Thanks for the suggestions, everyone. 谢谢大家的建议。 I ended up going with the multiple queries, as it apparently was not going to be as simple to do, as I had hoped. 我最终进行了多次查询,因为这样做显然不像我希望的那样简单。

    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;

Are you looking for this: 您在寻找这个吗?

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

Or you are trying to set 'task' to different values in different rows with a single statement? 或者您正在尝试使用单个语句将“任务”设置为不同行中的不同值? The latter is just not possible 后者是不可能的

I don't think this is possible with one statement. 我认为只有一种说法是不可能的。 You will need to create separate UPDATE statements: 您将需要创建单独的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

You can pass them into mysql_query() as one string separated by ';' 您可以将它们作为一个以';'分隔的字符串传递到mysql_query()中。 if you set mysql to accept multiple queries : 如果您将mysql设置为接受多个查询

Multiple queries seem to be supported. 似乎支持多个查询。 You just have to pass flag 65536 as mysql_connect's 5 parameter (client_flags) 您只需要传递标志65536作为mysql_connect的5个参数(client_flags)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM