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

114
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 - Jacob
3
可能是将数据插入MySQL表中,如果已存在则更新的重复问题。 - Jim Fell
4个回答

156

Jai的建议是正确的,你应该使用INSERT ... ON DUPLICATE KEY 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)

18
在针对具有多个唯一或主键的表使用INSERT ... ON DUPLICATE KEY UPDATE时,请务必小心。这是从MySQL文档中获取的信息。另外,从MySQL 5.5.24开始,在针对具有多个唯一或主键的表使用INSERT ... ON DUPLICATE KEY UPDATE语句也被标记为不安全。Bug 58637描述可在http://bugs.mysql.com/bug.php?id=58637中找到。 - broadband
1
可能需要使用 ALTER TABLE AggregatedData ADD UNIQUE (Timestamp) 创建 TimestampUNIQUE 约束。 - Avyakt
@broadband 你可以使用复合主键来避免这个错误。 - Kareem
最佳答案 - Plugie

18

尝试使用this

如果您指定了ON DUPLICATE KEY UPDATE,并且插入一行会导致在UNIQUE索引或PRIMARY KEY中出现重复值,则MySQL将对旧行执行[更新](http://dev.mysql.com/doc/refman/5.7/en/update.html)...

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

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


但是我的datenum不是主键。 - Mokus
那么在我的情况下,解决方案是什么呢?我尝试了这个,但没有解决:INSERT INTO forwind.aggregateddata (datenum,Timestamp,Min_F1_baro_20_) VALUES ('1','2','3') ON DUPLICATE KEY UPDATE datenum=datenum; - Mokus
1
datenum应该是唯一的吗?如果是,那么请添加一个唯一索引(如果尚未添加)。然后它就可以工作了。请参考http://dev.mysql.com/doc/refman/5.1/en/alter-table.html以了解如何添加唯一索引。 - Jai
现在我将datenum定义为唯一的,它运行良好,谢谢。 - Mokus
1
只是一个链接,也许给出答案。 - Andrew

1

这个方法还不错,但我们实际上可以将所有内容合并为一个查询。我在互联网上找到了不同的解决方案。最简单的,但只适用于MySQL的解决方案是:

INSERT INTO wp_postmeta (post_id, meta_key) 
SELECT 
  ?id, 
  ‘page_title’ 
FROM 
  DUAL 
WHERE 
  NOT EXISTS (
    SELECT 
      meta_id 
    FROM 
      wp_postmeta 
    WHERE 
      post_id = ?id 
      AND meta_key = ‘page_title’
  );
UPDATE 
  wp_postmeta 
SET 
  meta_value = ?page_title 
WHERE 
  post_id = ?id 
  AND meta_key = ‘page_title’;

Link to documentation.


0

我遇到了这样一种情况:我需要根据两个字段(都是外键)更新或插入表格,但我无法设置唯一约束条件(因此 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 始终会插入一行新数据!它只是删除了原始的已存在的数据! - jasie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接