mysql INSERT ... ON DUPLICATE KEY UPDATE

Coding-lover發表於2015-09-29

向資料庫插入記錄時,有時會有這種需求,當符合某種條件的資料存在時,去修改它,不存在時,則新增,也就是saveOrUpdate操作。這種控制可以放在業務層,也可以放在資料庫層,大多數資料庫都支援這種需求,如Oracle的merge語句,再如本文所講的MySQL中的INSERT … ON DUPLICATE KEY UPDATE語句。

該語句是基於唯一索引或主鍵使用,比如一個欄位a被加上了unique index,並且表中已經存在了一條記錄值為1,下面兩個語句會有相同的效果:

INSERT INTO table (a,b,c) VALUES (1,2,3)  
  ON DUPLICATE KEY UPDATE c=c+1;  

UPDATE table SET c=c+1 WHERE a=1; 

ON DUPLICATE KEY UPDATE後面可以放多個欄位,用英文逗號分割。使用ON DUPLICATE KEY UPDATE,最終如果插入了一個新行,則受影響的行數是1,如果修改了已存在的一行資料,則受影響的行數是2。

如果欄位b也被加上了unique index,則該語句和下面的update語句是等效的:

UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;  

如果a=1 OR b=2匹配了多行,則只有一行會被修改。通常的,在ON DUPLICATE KEY UPDATE語句中,我們應該避免多個唯一索引的情況。如果需要插入或更新多條資料,並且更新的欄位需要根據其它欄位來運算時,可以使用如下語句:

INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)  
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);  

在ON DUPLICATE KEY UPDATE後面使用VALUES()方法,這個語句等同於下面的兩個語句:

INSERT INTO table (a,b,c) VALUES (1,2,3)  
  ON DUPLICATE KEY UPDATE c=3;--1+2  
INSERT INTO table (a,b,c) VALUES (4,5,6)  
  ON DUPLICATE KEY UPDATE c=9;--4+5  

如果一個表中包含了一個auto_increment的欄位,每次insert資料後,可以通過last_insert_id()方法返回最後自動生成的值,如果通過INSERT … ON DUPLICATE KEY UPDATE語句修改了一條資料,那麼再通過last_insert_id()方法獲取的值將不正確,實際測試中是多了一個數,比如向表中增加了3條資料,那麼通過last_insert_id()方法得到的值是3,但是通過該語句修改了一條資料後,通過last_insert_id()方法得到的值是4。如果想解決該問題,可以通過如下語句:

INSERT INTO table (a,b,c) VALUES (1,2,3)  
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3; 

重點是這句id=LAST_INSERT_ID(id)。

英文原文:https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
本文來自:http://blog.csdn.net/ghsau/article/details/23557915
參考:
http://blog.csdn.net/kesaihao862/article/details/6718443
http://blog.sina.com.cn/s/blog_495697e60100lapz.html

相關文章