MySql表插入,如果不存在,否则更新


105
UPDATE AggregatedData SET datenum="734152.979166667", 
Timestamp="2010-01-14 23:30:00.000" WHERE datenum="734152.979166667";

如果datenum存在,它就可以工作,但是如果不存在,我想将此数据作为新行插入datenum

更新

datenum是唯一的,但这不是主键


2
“ datenum”是否唯一?您可以使用INSERT ... ON DUPLICATE KEY UPDATE
雅各布

Answers:


143

Jai是正确的,您应该使用INSERT ... ON DUPLICATE KEY UPDATE

请注意,由于它是唯一键,因此不需要在update子句中包含datenum,因此它不应更改。您确实需要包括表中的所有其他列。您可以使用该VALUES()函数来确保在更新其他列时使用正确的值。

这是使用适用INSERT ... ON DUPLICATE KEY UPDATE于MySQL 的正确语法重写的更新:

INSERT INTO AggregatedData (datenum,Timestamp)
VALUES ("734152.979166667","2010-01-14 23:30:00.000")
ON DUPLICATE KEY UPDATE 
  Timestamp=VALUES(Timestamp)

18
在具有多个唯一或主键的表上使用INSERT ... ON DUPLICATE KEY UPDATE时要小心。取自MySQL文档另外,从MySQL 5.5.24开始,针对具有多个唯一或主键的表的INSERT ... ON DUPLICATE KEY UPDATE语句也被标记为不安全。(错误#11765650,错误#58637)错误58637说明bugs.mysql.com/bug.php?id=58637
宽带

1
它可能需要创建 UNIQUE用于约束TimestampALTER TABLE AggregatedData ADD UNIQUE (Timestamp)
Avyakt

@broadband您可以使用组合键来避免此错误
Kareem

16

尝试使用这个

如果您指定ON DUPLICATE KEY UPDATE,则会插入一行,这将导致旧行的UNIQUE index orPRIMARY KEY , MySQL performs an [UPDATE`](PRIMARY KEY UPDATE`](http://dev.mysql.com/doc/refman/5.7/en/update.html)中的值重复。 ..

ON DUPLICATE KEY UPDATE子句可以包含多个列分配,以逗号分隔。

使用ON DUPLICATE KEY UPDATE,如果将行插入为新行,则每行的受影响行值为1;如果更新了现有行,则为2;如果将现有行设置为其当前值,则为0。如果在连接到mysqld时指定CLIENT_FOUND_ROWS标志,则在现有行设置为其当前值mysql_real_connect()时,受影响的行值为1(而不是0)...


但是我的datenum不是主键。
OHLÁLÁ

因此,在我的情况下,解决方案是什么,我尝试了此解决方案,但没有任何解决方案:在DUPLICATE KEY UPDATE datenum = datenum;
OHLÁLÁ

1
datenum应该是唯一的吗?如果是,则向其添加唯一索引(如果尚未添加),则它将起作用。请参阅dev.mysql.com/doc/refman/5.1/en/alter-table.html对于如何广告的唯一指标
武汉佳

现在我所定义的datenum为独特的,它的工作很好,谢谢
OHLÁLÁ

1
只是一个链接,也许给出答案。
安德鲁

0

我遇到一种情况,我需要根据无法设置UNIQUE约束的两个字段(两个外键)来更新或插入到表中(因此INSERT ... ON DUPLICATE KEY UPDATE将无法工作)。这是我最终使用的内容:

replace into last_recogs (id, hasher_id, hash_id, last_recog) 
  select l.* from 
    (select id, hasher_id, hash_id, [new_value] from last_recogs 
     where hasher_id in (select id from hashers where name=[hasher_name])
     and hash_id in (select id from hashes where name=[hash_name]) 
     union 
     select 0, m.id, h.id, [new_value] 
     from hashers m cross join hashes h 
     where m.name=[hasher_name] 
     and h.name=[hash_name]) l 
  limit 1;

这个示例来自我的一个数据库,其中输入参数(两个名称和一个数字)被替换为[hasher_name],[hash_name]和[new_value]。嵌套的SELECT ... LIMIT 1提取现有记录或新记录中的第一个(last_recogs.id是自动增量主键),并将其用作输入到REPLACE INTO中的值。


替换总是插入新行!它只是删除原始的,已经存在的一个!
jasie
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.