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

Posted

技术标签:

【中文标题】MySql 表插入,如果不存在,否则更新【英文标题】:MySql Table Insert if not exist otherwise update 【发布时间】:2011-08-27 04:02:50 【问题描述】:
UPDATE AggregatedData SET datenum="734152.979166667", 
Timestamp="2010-01-14 23:30:00.000" WHERE datenum="734152.979166667";

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

更新

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

【问题讨论】:

“datenum”是唯一的吗?如果是,您可以使用INSERT ... ON DUPLICATE KEY UPDATE。 Insert into a mysql table or update if exists的可能重复 【参考方案1】:

尝试使用this:

如果您指定ON DUPLICATE KEY UPDATE,并且插入的行会导致旧行的UNIQUE index orPRIMARY KEY, MySQL performs an [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 不是主键。 所以在我的情况下,解决方案是什么,我尝试了这个,没有任何解决方案:INSERT INTO forwind.aggregateddata (datenum,Timestamp,Min_F1_baro_20_) VALUES ('1','2','3 ') ON DUPLICATE KEY UPDATE datenum=datenum; datenum 应该是唯一的吗?如果是,则向其添加唯一索引(如果尚未添加)然后它将起作用。请参阅 dev.mysql.com/doc/refman/5.1/en/alter-table.html 了解如何投放 UNIQUE 索引 现在我将 datenum 定义为唯一的,它工作正常,谢谢 只是一个链接,也许会给一个答案。【参考方案2】:

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

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

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

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

【讨论】:

在对具有多个唯一键或主键的表使用 INSERT ... ON DUPLICATE KEY UPDATE 时要小心。取自MySQL documentation:此外,从 MySQL 5.5.24 开始,针对具有多个唯一键或主键的表的 INSERT ... ON DUPLICATE KEY UPDATE 语句也被标记为不安全。 (错误 #11765650、错误 #58637) 错误 58637 描述 bugs.mysql.com/bug.php?id=58637 可能需要使用ALTER TABLE AggregatedData ADD UNIQUE (Timestamp)Timestamp创建UNIQUE约束 @broadband 你可以使用composite key 来避免这个错误【参考方案3】:

我遇到了一种情况,我需要根据两个字段(两个外键)更新或插入表,而我无法在这两个字段上设置 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 的值输入。

【讨论】:

REPLACE 总是插入一个新行!它只是删除了原来的,已经存在的!

以上是关于MySql 表插入,如果不存在,否则更新的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL从另一个表更新数据,如果存在,否则插入[重复]

如果存在则如何更新,否则在php mysql中插入[重复]

mysql:如果不存在则插入记录,否则返回记录的ID

SQL 查询 - 如果存在则更新,否则插入

sql server 判断记录存在更新不存在插入

如果 id 存在则更新,否则插入 (ODBC)