INSERT ... ON DUPLICATE KEY UPDATE 没有按我预期的那样工作

Rel*_*lax 8 mysql insert duplication update

我有一个名为“示例”的表

CREATE TABLE IF NOT EXISTS `example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

如果不存在,我想插入值,如果值存在则更新,所以我使用以下语句:

INSERT INTO example (a, b, c) VALUES (1,2,3) 
  ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);
Run Code Online (Sandbox Code Playgroud)

执行上述查询后,该表如下所示:

在此处输入图片说明

再次执行上面的语句,结果如下:

在此处输入图片说明

我的陈述有什么问题?

Sha*_*med 8

那么这是您正在使用的插入位:

插入示例 (a, b, c) VALUES (1,2,3) ....

在这里您没有指定id(要检查重复的主键)。因为,它被设置为自动增量,它会自动将下一行只为列中的值的ID abc

在这种情况下,当您提供主键(您要检查是否重复)以及行数据的其余部分时,会更新该行。如果您需要根据记录 ID 检查和更新,您还必须提供KEY,在您的情况下是id.

尝试这样的事情:

INSERT INTO example (id, a, b, c) VALUES (1,1,2,3) ON DUPLICATE KEY UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);
Run Code Online (Sandbox Code Playgroud)

现在,如果id重复,该行将更新。


Rol*_*DBA 8

您的原始查询

INSERT INTO example (a, b, c) VALUES (1,2,3) ON DUPLICATE KEY
UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);
Run Code Online (Sandbox Code Playgroud)

如果您考虑(a,b,c)使用唯一键,则需要做两件事

一、添加唯一索引

ALTER TABLE example ADD UNIQUE KEY abc_ndx (a,b,c);
Run Code Online (Sandbox Code Playgroud)

所以表结构将变成

CREATE TABLE IF NOT EXISTS `example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY abc_ndx (a,b,c)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

其次,您需要完全更改查询。为什么 ?

如果(a,b,c)是唯一的,则运行

INSERT INTO example (a, b, c) VALUES (1,2,3) ON DUPLICATE KEY
UPDATE a = VALUES(a), b = VALUES(b), c = VALUES(c);
Run Code Online (Sandbox Code Playgroud)

将保持(a,b,c)完全相同的值。什么都不会改变。

因此,我建议将查询更改为以下内容

INSERT IGNORE INTO example (a, b, c) VALUES (1,2,3);
Run Code Online (Sandbox Code Playgroud)

查询更简单,并且具有相同的最终结果。

  • 代替`INSERT IGNORE INTO example (a, b, c) VALUES (1,2,3);`,你应该使用`INSERT INTO example (a, b, c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=id;` -- 后者也将无操作,但它不会忽略其他不相关的错误。 (2认同)