【问题标题】:mysql bulk update multiple records at oncemysql一次批量更新多条记录
【发布时间】:2020-09-21 04:41:19
【问题描述】:

我有如下数据:

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 = ?

无需遍历列表并运行此查询 X 次,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

【问题讨论】:

  • 不需要循环,它将根据您的WHERE id = ? where 条件更新所有匹配记录。
  • 但我需要更改各种表+列组合的添加、编辑、删除或查看
  • SQL 中的更新默认是批量更新。这意味着更新可以针对 WHERE 子句允许的尽可能多的记录。
  • @TimBiegeleisen,对,但我可能需要供应商 + 城市的组合为 1、1、0、0,而我需要供应商 + zip 的组合为 0、1、0、1,所以在那个你将如何处理批量更新?
  • @dataviews 根据您的表格,您在上面给定的表格中存储其他表格的详细信息,并且您需要动态更新,然后可能需要循环。

标签: mysql mysql-python


【解决方案1】:

在您的情况下,更新多行最接近的方法是使用 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 = ?;

如果您想将table_namecolumn_name 都放入CASE 表达式中,那就更复杂了。

坦率地说,只编写循环并一次执行这一行更容易。

如果您有一个唯一键,例如由 (id, table_name, column_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 子句。阅读文档了解更多详情。

【讨论】:

  • 因此,如果您必须逐行执行此操作,如果中途某事失败或退出会发生什么?如果所有更新都失败,创建存储过程并回滚会更好吗?
  • 如果您一次循环执行一行,如果一个失败,或者全部失败,或者任何您想要的,您可以回滚整个批次。或者你可以忽略失败并尽可能多地提交成功。由你决定。我不能说什么是“更好”,因为这取决于您的项目需要什么,而您比我更了解这一点。
猜你喜欢
  • 2018-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-13
  • 2020-12-11
相关资源
最近更新 更多