mysql一次批量更新多条记录

mysql一次批量更新多条记录,mysql,mysql-python,Mysql,Mysql Python,我有以下数据: id table column add edit delete view 1 vendors city 0 0 0 1 1 vendors state 0 0 0 1 1 vendors zip 0 0 0 1 我正在尝试使用类似的查询执行批量更新: UPDATE user_perms SET add = ?, edit = ?, delete = ?, view = ? WHERE id

我有以下数据:

id  table   column add edit delete view
1   vendors city    0   0   0      1
1   vendors state   0   0   0      1
1   vendors zip     0   0   0      1
我正在尝试使用类似的查询执行批量更新:

UPDATE user_perms SET add = ?, edit = ?, delete = ?, view = ?
WHERE id = ? AND table_name = ? AND column_name = ?
不必循环遍历列表并多次运行此查询,MySQL是否支持一次性批量更新

创建表STMT:

CREATE TABLE `user_perms` (
   `up_id` int unsigned NOT NULL AUTO_INCREMENT,
   `id` int unsigned DEFAULT NULL,
   `table_name` varchar(255) DEFAULT NULL,
   `column_name` varchar(255) DEFAULT NULL,
   `add` int unsigned DEFAULT NULL,
   `edit` int unsigned DEFAULT NULL,
   `delete` int unsigned DEFAULT NULL,
   `view` int unsigned DEFAULT NULL,
   PRIMARY KEY (`up_id`),
   UNIQUE KEY `up_id_UNIQUE` (`up_id`),
   KEY `fk_idx` (`id`),
   CONSTRAINT `fk_id` FOREIGN KEY (`id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE
 ) ENGINE=InnoDB AUTO_INCREMENT=1659 DEFAULT CHARSET=utf8

在您的情况下,最接近更新多行的方法是使用case表达式设置值:

UPDATE user_perms 
SET add    = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,
    edit   = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,
    delete = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,
    view   = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END
WHERE id = ? AND table_name = ?;
如果您想将
表名称
列名称
都放入CASE表达式中,则会更加复杂

坦率地说,只编写循环并一次执行一行比较容易

例如,如果您有一个由列
(id,table\u name,column\u name)
组成的唯一键,以便SQL能够在插入重复行时进行检测,则可以执行以下操作:

INSERT INTO user_perms (id, table_name, column_name, add, edit, delete, view)
VALUES (1, 'vendors', 'city',  0, 0, 0, 1),
       (1, 'vendors', 'state', 0, 0, 0, 1),
       (1, 'vendors', 'zip',   0, 0, 0, 1) 
       -- any number of additional tuples follow
ON DUPLICATE KEY UPDATE add = VALUES(add), edit = VALUES(edit), 
       delete = VALUES(delete), view = VALUES(view);

如果这样做有效,则不需要先删除行。如果插入的数据与现有行不冲突,但如果插入的值与表上的唯一键冲突,则将插入新行,根据
UPDATE
子句,它仅更新您设置的列。阅读文档了解更多详细信息。

在您的情况下,更新多行最接近的方法是使用大小写表达式设置值:

UPDATE user_perms 
SET add    = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,
    edit   = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,
    delete = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END,
    view   = CASE column_name WHEN 'city' THEN ? WHEN 'state' THEN ? WHEN 'zip' THEN ? END
WHERE id = ? AND table_name = ?;
如果您想将
表名称
列名称
都放入CASE表达式中,则会更加复杂

坦率地说,只编写循环并一次执行一行比较容易

例如,如果您有一个由列
(id,table\u name,column\u name)
组成的唯一键,以便SQL能够在插入重复行时进行检测,则可以执行以下操作:

INSERT INTO user_perms (id, table_name, column_name, add, edit, delete, view)
VALUES (1, 'vendors', 'city',  0, 0, 0, 1),
       (1, 'vendors', 'state', 0, 0, 0, 1),
       (1, 'vendors', 'zip',   0, 0, 0, 1) 
       -- any number of additional tuples follow
ON DUPLICATE KEY UPDATE add = VALUES(add), edit = VALUES(edit), 
       delete = VALUES(delete), view = VALUES(view);

如果这样做有效,则不需要先删除行。如果插入的数据与现有行不冲突,但如果插入的值与表上的唯一键冲突,则将插入新行,根据
UPDATE
子句,它仅更新您设置的列。阅读文档了解更多详细信息。

无需循环,它将根据您的
WHERE id=?
WHERE条件更新所有匹配记录。但我需要更改各种表+列组合的添加、编辑、删除或视图默认情况下,SQL中的支持日期是批量更新。这意味着更新可以针对
WHERE
子句允许的记录数。@TimBiegeleisen,对,但我可能需要供应商+城市的组合为1,1,0,0,而我需要供应商+zip的组合为0,1,0,1那么,在这种情况下,您将如何处理批量更新?@dataviews根据您的表,您正在上述给定表中存储其他表的详细信息,并且需要动态更新,那么您可能需要循环。不需要循环,它将根据您的
WHERE id=?
WHERE条件更新所有匹配的记录。但我需要更改添加、编辑、,默认情况下,SQL中各种表+列组合的删除或查看支持日期是批量更新。这意味着更新可以针对
WHERE
子句允许的记录数。@TimBiegeleisen,对,但我可能需要供应商+城市的组合为1,1,0,0,而我需要供应商+zip的组合为0,1,0,1那么,在这种情况下,您将如何处理批量更新?@dataviews根据您的表,您正在上面给定的表中存储其他表的详细信息,并且需要动态更新,那么您可能需要循环。因此,如果您必须逐行执行此操作,那么如果中途出现故障或退出,会发生什么情况?创建一个存储过程并在所有更新都失败时回滚是否更好?如果在循环中一次执行一行,则可以在其中一行失败时回滚整个批处理,或者在所有更新都失败时回滚整个批处理,或者根据需要进行回滚。或者,你可以忽略失败,尽可能多地承诺成功。由你决定。我不能说什么“更好”,因为这取决于你的项目需要什么,你比我更清楚。所以,如果你必须一行一行地做,如果中途某个项目失败或退出,会发生什么?创建一个存储过程并在所有更新都失败时回滚是否更好?如果在循环中一次执行一行,则可以在其中一行失败时回滚整个批处理,或者在所有更新都失败时回滚整个批处理,或者根据需要进行回滚。或者,你可以忽略失败,尽可能多地承诺成功。由你决定。我不能说什么“更好”,因为这取决于你的项目需要什么,你比我更清楚这一点。