萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> sql插入數據已經存在,則執行update更新

sql插入數據已經存在,則執行update更新

這個例子其實是非常的簡單了就是要實現sql插入數據時,如果已經存在,則執行update更新了,這樣對於sql與程序來講是非常的簡潔的,下面就和小編一起來深入的分析一下吧.

在很多項目中,我們需要對數據進行不斷的調用和更新,如果有新的數據過來,還要把它加入到數據庫中。其中非常重要的一種情況就是,我們不知道傳過來的數據是不是原本數據庫中就已經有了的記錄,所以我們常常需要先通過抓取數據,判斷是否存在,如果存在執行update,如果不存在執行insert,這樣就要進行兩次數據庫操作,第一次是查詢,第二次是更新或插入,有沒有一種方法可以只需要執行一次操作即可呢?答案是有的。

INSERT ... ON DUPLICATE KEY UPDATE 方法可以幫助我們非常好的解決這一問題。讓我們來看一個例子:

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

這一個語句就可以實現,在插入(1,2,3)這條記錄的時候,檢查是否存在a=1,如果有a=1的記錄,那麼更新a=1這條記錄,相當於執行了一次下面這個語句:

UPDATE table SET b=b-1,c=c+1 WHERE a=1;

如果數據庫中不存在a=1這條記錄,那麼就插入新的記錄。

使用INSERT ... ON DUPLICATE KEY UPDATE的前提是,a字段被設置為“唯一鍵”索引,否則該方法是無效的。

再看一些例子

該語句是基於唯一索引或主鍵使用,比如一個字段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)。

還有一種方法是使用ignore,我們來看一個例子:

INSERT ignore INTO a(id, type)  VALUES  ( 11, 22)

這個語句中使用了ignore,意思是:如果數據庫中存在一條記錄id=11,那麼就不執行insert操作(忽略),只有上述條件不滿足時才執行插入操作。ignore方法也要求這裡的id為唯一鍵(主鍵默認就是是唯一鍵,因此id可以是主鍵)

另外,還有一種方法是replace into,它的使用方法和insert into一樣,但是和上面的ignore效果不同,如果數據庫中已經存在id=11,那麼強制替換id=11這條記錄的type為22。

看個例子


下面通過代碼說明之間的區別,如下:

create table testtb(
id int not null primary key,
name varchar(50),
age int
);
insert into testtb(id,name,age)values(1,"bb",13);
select * from testtb;
insert ignore into testtb(id,name,age)values(1,"aa",13);
select * from testtb;//仍是1,“bb”,13,因為id是主鍵,出現主鍵重復但使用了ignore則錯誤被忽略
replace into testtb(id,name,age)values(1,"aa",12);
select * from testtb; //數據變為1,"aa",12


總結一下:

如果要實現插入數據時檢查是否已經存在某個唯一鍵的數據,如果存在,則替換該記錄的其他字段,我們可以使用三種方法來實現插入數據時判斷是否存在對應鍵的記錄,分別是INSERT ... ON DUPLICATE KEY UPDATE、insert gnore into和replace into。其中INSERT ... ON DUPLICATE KEY UPDATE和replace into可以實現如果已經存在對應鍵的記錄時,替換該記錄的其他字段。

copyright © 萬盛學電腦網 all rights reserved