首页 > 解决方案 > ON DUPLICATE KEY UPDATE 非索引列

问题描述

我有一个代码,它使用来自 Sybase 数据库的数据更新一些 mySQL 表。表结构完全相同。由于将来表的数量可能会增加,因此我编写了一个 Python 脚本,该脚本循环遍历一组表名,并根据每个表中的列数,动态更改插入语句:

'''insert into databaseName.{} ({}) values ({})'''.format(table, columns, parameters)

如您所见,值参数不是硬编码的,这导致了我无法修改此查询以执行“ON DUPLICATE KEY UPDATE”的问题。

例如,插入语句可能如下所示:

insert into databaseName.table_foo (col1,col2,col3,col4,col5) values (%s,%s,%s,%s,%s)

或者

insert into databaseName.table_bar (col1,col2,col3) values (%s,%s,%s)

如何在此处使用“ON DUPLICATE KEY UPDATE”来使用相应的非索引值更新非索引列?

如果需要,我可以通过包含更多详细信息来更新此问题。

标签: pythonmysql

解决方案


最简单的解决方案是这样的:

'''replace into databaseName.{} ({}) values ({})'''.format(table, columns, parameters)

这与 IODKU 的工作方式类似,如果值与表的 PRIMARY KEY 或 UNIQUE KEY 冲突,它会替换行,覆盖其他列,而不是导致重复键错误。

不同之处在于 REPLACE 对旧行执行 DELETE,然后对新行执行 INSERT。而 IODKU 则执行 INSERT 或 UPDATE。我们知道这一点,因为如果您在表上创建触发器,您将看到激活了哪些触发器。

无论如何,在这种情况下,使用 REPLACE 会使您的任务变得更加简单。

如果必须使用 IODKU,则需要update在末尾添加更多语法。不幸的是,没有“将所有列分别分配给新行的值”的语法。您必须单独分配它们。

对于 MySQL 8.0.19 或更高版本,请使用以下语法:

INSERT INTO t1 (a,b,c) VALUES (?,?,?) AS new
  ON DUPLICATE KEY UPDATE a = new.a, b = new.b, c = new.c;

在早期的 MySQL 中,使用以下语法:

INSERT INTO t1 (a,b,c) VALUES (?,?,?)
  ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);

推荐阅读