有没有办法使用ON DUPLICATE KEY更新我要插入的所有内容?

Nea*_*eal 68 mysql insert on-duplicate-key

我知道ON DUPLICATE KEY UPDATE如果已经存在该密钥的记录,您可以使用更新某个值,

我可以做这个:

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

但是,如何在不必写出两次列和值的情况下执行此操作?

Lig*_*ica 93

不幸的是.

您可以通过不必重复该值来获得一半:

INSERT INTO `tableName` (`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)

但是你仍然需要列出列.

  • 从 MySQL 8.0.20 开始,不推荐使用 VALUES() 来引用新行和列,并且将来可能会删除 https://dev.mysql.com/doc/refman/8.0/en/miscellaneous -functions.html#function_values (4认同)
  • @Sohaib:`更新a = VALUES(a)+ a,b = VALUES(b)+ b,c = VALUES(c)+ c`? (3认同)

小智 38

使用 REPLACE INTO

意思REPLACE INTO是如果新记录显示新的键值,则它将作为新记录插入.

如果新记录具有与预先存在的记录匹配的键值,则将忽略密钥违规,并且新记录将替换预先存在的记录.

  • 注意:使用`REPLACE`,如果记录的键与已存在的键匹配,则将删除旧行(s!),并插入新行**.如果你搞乱触发器或外键约束,这可能是一个大问题. (58认同)
  • 啊,那可能会好得多.值得注意的是,查询中未明确给出的所有字段都将是默认的,这显然不同于"ON DUPLICATE KEY UPDATE"行为. (5认同)
  • 好点子.我想,你冒着一些重大连锁反应的风险. (3认同)

Jav*_*r P 13

如果它有用,我提出了一个查询,以避免手动编写"on duplicate"查询的最后一部分,对于版本> = 5.0:

SELECT GROUP_CONCAT( CONCAT(COLUMN_NAME,"=values(", COLUMN_NAME,")") SEPARATOR ", ") FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'database_name' AND TABLE_NAME = 'table_name';
Run Code Online (Sandbox Code Playgroud)

它的输出是这样的:

a=values(a), b=values(b), c=values(c), d=values(d)
Run Code Online (Sandbox Code Playgroud)

在具有列a,b,c和d的表上,因此您可以追加到查询的第一部分:

INSERT INTO `tableName` (`a`,`b`,`c`, `d`) VALUES (1,2,3,4) ON DUPLICATE KEY UPDATE a=values(a), b=values(b), c=values(c), d=values(d)
Run Code Online (Sandbox Code Playgroud)

更新: 对于很长的列列表,您可能会看到截断的输出,您可以在上面的查询之前使用此语句(感谢Uncle iroh):

SET SESSION group_concat_max_len = 1000000;
Run Code Online (Sandbox Code Playgroud)

  • 喜欢这个.有时我会在你非常有用的查询之前需要这个.SET SESSION group_concat_max_len = 1000000; (2认同)

mow*_*ker 6

根据 @BhendiGawaar 对 @Lightness Races in Orbit 的回答的评论,这里是 MySQL 8.019+ 版本:

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new
  ON DUPLICATE KEY UPDATE c = new.a+new.b;
Run Code Online (Sandbox Code Playgroud)

或者

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new(m,n,p)
  ON DUPLICATE KEY UPDATE c = m+n;
Run Code Online (Sandbox Code Playgroud)

set也适用于:

INSERT INTO t1 SET a=1,b=2,c=3 AS new
  ON DUPLICATE KEY UPDATE c = new.a+new.b;

INSERT INTO t1 SET a=1,b=2,c=3 AS new(m,n,p)
  ON DUPLICATE KEY UPDATE c = m+n;
Run Code Online (Sandbox Code Playgroud)

直接从MySQL 文档复制

关于使用的弃用警告VALUES

从 MySQL 8.0.20 开始,不推荐使用 VALUES() 来引用新行和新列,并且可能会在 MySQL 的未来版本中删除。相反,请使用行和列别名,如本节接下来的几段所述。