說明:一般我們使用MYSQL插入記錄時,類似於這樣的語句:
insert into table_name(email,phone,user_id) values(‘[email protected]’,’99999′,’9999′) ,
但是有時候我們可能還有這樣的需求:判斷數據是否存在, 如果不存在,則插入,.如果存在,則更新(或者不做任何操作)。
方案一:REPLACE語法
replace的語法格式為:
1. replace into table_name(col_name, …) values(…)
2. replace into table_name(col_name, …) select …
3. replace into table_name set col_name=value, …
算法說明:
REPLACE的運行與INSERT很相像,但是如果舊記錄與新記錄有相同的值,則在新記錄被插入之前,舊記錄被刪除,即:
1. 嘗試把新行插入到表中
2. 當因為對於主鍵或唯一關鍵字出現重復關鍵字錯誤而造成插入失敗時:
從表中刪除含有重復關鍵字值的沖突行
再次嘗試把新行插入到表中
舊記錄與新記錄有相同的值的判斷標准就是:表有一個PRIMARY KEY或UNIQUE索引,否則,使用一個REPLACE語句沒有意義。
該語句會與INSERT相同,因為沒有索引被用於確定是否新行復制了其它的行。
返回值:
REPLACE語句會返回一個數,來指示受影響的行的數目。該數是被刪除和被插入的行數的和。
受影響的行數可以容易地確定是否REPLACE只添加了一行,或者是否REPLACE也替換了其它行:檢查該數是否為1(添加)或更大(替換)。
示例:
eg:(phone字段為唯一索引)
replace into table_name(email,phone,user_id) values(‘test569′,’99999′,’123′)
另外:在 SQL Server 中可以這樣處理:
if not exists (select phone from t where phone= ’1′)
insert into t(phone, update_time) values(’1′, getdate())
else
update t set update_time = getdate() where phone= ’1′
更多信息請看:http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#replace
方案二:ON DUPLICATE KEY UPDATE
如上所寫,你也可以在INSERT INTO…..後面加上 ON DUPLICATE KEY UPDATE方法來實現。
如果您指定了ON DUPLICATE KEY UPDATE,並且插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重復值,
則執行舊行UPDATE。例如,如果列a被定義為UNIQUE,並且包含值1,則以下兩個語句具有相同的效果:
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)
->ON DUPLICATE KEY UPDATE c=c+1;
mysql>UPDATE table SET c=c+1 WHERE a=1;
如果行作為新記錄被插入,則受影響行的值為1;如果原有的記錄被更新,則受影響行的值為2。
注釋:如果列b也是唯一列,則INSERT與此UPDATE語句相當:
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
如果a=1 OR b=2與多個行向匹配,則只有一個行被更新。通常,您應該盡量避免對帶有多個唯一關鍵字的表使用ON DUPLICATE KEY子句。
您可以在UPDATE子句中使用VALUES(col_name)函數從INSERT…UPDATE語句的INSERT部分引用列值。
換句話說,如果沒有發生重復關鍵字沖突,則UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函數特別適用於多行插入。VALUES()函數只在INSERT…UPDATE語句中有意義,其它時候會返回NULL。
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
-> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
本語句與以下兩個語句作用相同:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
-> ON DUPLICATE KEY UPDATE c=3;
mysql> INSERT INTO table (a,b,c) VALUES (4,5,6)
-> ON DUPLICATE KEY UPDATE c=9;
當您使用ON DUPLICATE KEY UPDATE時,DELAYED選項被忽略。
示例:
例子1:向一個表裡寫入數據時,如果沒有相關數據就插入,如果有了就更新相關值。
(displayid為主鍵)
INSERT INTO
cdqsscms_house_hot_top (displayid,x1,x2,x3,x4,x5,last_updated)
VALUES(2820,1,63,79,54,45,1311053750)
ON DUPLICATE KEY UPDATE
x1=x1+ 1,
x2=x2+ 63,
x3=x3+ 79,
x4=x4+ 54,
x5=x5+ 45,
last_updated= 1311053750
例子2(結合 select ..from…):將一個表的數據導入到另外一個表中,數據的重復性就得考慮(如下)。
唯一索引為:email
INSERT INTO table_name1(title,first_name,last_name,email,phone,user_id,role_id,status,campaign_id)
SELECT ”,”,”,table_name2.email,table_name2.phone,NULL,NULL,’pending’,29
FROM table_name2
WHERE table_name2.status = 1
ON DUPLICATE KEY UPDATE table_name1.status = ‘pending’
語句的關鍵地方,都已高亮出來~
其它關鍵:DELAYED 做為快速插入,並不是很關心失效性,提高插入性能。
IGNORE 只關注主鍵對應記錄是不存在,無則添加,有則忽略。
更多信息請看: http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#insert
特別說明:在MYSQL中UNIQUE 索引將會對null字段失效,也就是說(a字段上建立唯一索引):