我知道你可以一次插入多行,是否有一种方法可以一次更新多行(如在,在一个查询)在MySQL?

编辑: 例如,我有以下内容

Name   id  Col1  Col2
Row1   1    6     1
Row2   2    2     3
Row3   3    9     5
Row4   4    16    8

我想将以下所有更新组合成一个查询

UPDATE table SET Col1 = 1 WHERE id = 1;
UPDATE table SET Col1 = 2 WHERE id = 2;
UPDATE table SET Col2 = 3 WHERE id = 3;
UPDATE table SET Col1 = 10 WHERE id = 4;
UPDATE table SET Col2 = 12 WHERE id = 4;

当前回答

下面是简单的方法

update my_table m, -- let create a temp table with populated values
    (select 1 as id, 20 as value union -- this part will be generated
     select 2 as id, 30 as value union -- using a backend code
     -- for loop 
     select N as id, X as value
        ) t
set m.value = t.value where t.id=m.id -- now update by join - quick

其他回答

是的,这是可能的-你可以使用INSERT…重复密钥更新。

举个例子:

INSERT INTO table (id,Col1,Col2) VALUES (1,1,1),(2,2,3),(3,9,3),(4,10,12)
ON DUPLICATE KEY UPDATE Col1=VALUES(Col1),Col2=VALUES(Col2);

是的. .可以使用INSERT ON DUPLICATE KEY UPDATE sql语句.. 语法: INSERT INTO table_name (a,b,c) VALUES (1,2,3),(4,5,6) 重复键更新a=VALUES(a),b=VALUES(b),c=VALUES(c)

我从@newtover中得到答案,并使用MySql 8中的新json_table函数扩展它。这允许你创建一个存储过程来处理工作负载,而不是在代码中构建自己的SQL文本:

drop table if exists `test`;
create table `test` (
  `Id` int,
  `Number` int,
  PRIMARY KEY (`Id`)
);
insert into test (Id, Number) values (1, 1), (2, 2);

DROP procedure IF EXISTS `Test`;
DELIMITER $$
CREATE PROCEDURE `Test`(
    p_json json
)
BEGIN
    update test s
        join json_table(p_json, '$[*]' columns(`id` int path '$.id', `number` int path '$.number')) v 
        on s.Id=v.id set s.Number=v.number;
END$$
DELIMITER ;

call `Test`('[{"id": 1, "number": 10}, {"id": 2, "number": 20}]');
select * from test;

drop table if exists `test`;

它比纯SQL慢了几毫秒,但我很高兴接受打击,而不是在代码中生成SQL文本。不确定它对巨大记录集的性能如何(JSON对象的最大大小为1Gb),但我在一次更新10k行时一直使用它。

你可以修改一个名为“多语句”的设置,它会禁用MySQL为防止(多个)注入命令而实现的“安全机制”。典型的MySQL的“辉煌”实现,它也阻止用户进行有效的查询。

这里(http://dev.mysql.com/doc/refman/5.1/en/mysql-set-server-option.html)有一些关于设置的C实现的信息。

如果你正在使用PHP,你可以使用mysqli来做多个语句(我认为PHP已经发布了mysqli一段时间了)

$con = new mysqli('localhost','user1','password','my_database');
$query = "Update MyTable SET col1='some value' WHERE id=1 LIMIT 1;";
$query .= "UPDATE MyTable SET col1='other value' WHERE id=2 LIMIT 1;";
//etc
$con->multi_query($query);
$con->close();

希望这能有所帮助。

UPDATE `your_table` SET 

`something` = IF(`id`="1","new_value1",`something`), `smth2` = IF(`id`="1", "nv1",`smth2`),
`something` = IF(`id`="2","new_value2",`something`), `smth2` = IF(`id`="2", "nv2",`smth2`),
`something` = IF(`id`="4","new_value3",`something`), `smth2` = IF(`id`="4", "nv3",`smth2`),
`something` = IF(`id`="6","new_value4",`something`), `smth2` = IF(`id`="6", "nv4",`smth2`),
`something` = IF(`id`="3","new_value5",`something`), `smth2` = IF(`id`="3", "nv5",`smth2`),
`something` = IF(`id`="5","new_value6",`something`), `smth2` = IF(`id`="5", "nv6",`smth2`) 

//你只是在php中构建它

$q = 'UPDATE `your_table` SET ';

foreach($data as $dat){

  $q .= '

       `something` = IF(`id`="'.$dat->id.'","'.$dat->value.'",`something`), 
       `smth2` = IF(`id`="'.$dat->id.'", "'.$dat->value2.'",`smth2`),';

}

$q = substr($q,0,-1);

所以你可以用一个查询更新孔表