Mysql 使用主键和唯一键更新重复键

Mysql on duplicate key update with primary key and unique key

我有一个 table,它有一个自动递增的主键和一个唯一键:

CREATE TABLE `product` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`canonical_url` varchar(750) CHARACTER SET latin1 NOT NULL,
...
PRIMARY KEY (`id`),
UNIQUE KEY `canonical_url_idx` (`canonical_url`)

如果 canonical_url 已经存在,我将使用重复键功能更新记录:

"INSERT INTO product(id, canonical_url, name VALUES(?, ? ?) ON DUPLICATE KEY UPDATE name=VALUES(name), id=LAST_INSERT_ID(id)"

KeyHolder productKeyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(conn -> {
  PreparedStatement ps = conn.prepareStatement(productSql, new String[] {"id"});
  ps.setInt(1, id);
  ps.setString(2, canonicalUrl);
  ps.setString(3, name);
}, productKeyHolder);

final int productId = productKeyHolder.getKey().intValue();

问题是我遇到了这个错误:

getKey 方法只应在返回单个密钥时使用。当前键项包含多个键:[{GENERATED_KEY=594}, {GENERATED_KEY=595}]

有人知道是什么原因造成的吗?

我自己 运行 对此感兴趣。根据此处的文档:

https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, and 2 if an existing row is updated.

因此,当您的查询执行时,如果插入了一条新记录,则会返回它的 ID。如果记录已经存在,则更新现有记录。如果因为值全部匹配而无需更新,则返回一个 ID,修改的行数为 0。但是,如果记录已更新,则返回 ID,修改的行数为 2。 keyholder 假设两行已被修改(即使只有一行被修改)并且错误地返回 ID 加上下一个顺序 ID(即 ID 加 1)。

为了解决这个问题,我只是在尝试调用 getKey 之前检查了 getKeys 中的计数。如果 getKeys 中有多个值,我不会调用 getKey。