1. 程式人生 > >mysql INSERT ... ON DUPLICATE KEY UPDATE語句

mysql INSERT ... ON DUPLICATE KEY UPDATE語句

not 股票 目的 一個 lin arc sta int prim

網上關於INSERT ... ON DUPLICATE KEY UPDATE大多數文章都是同一篇文章轉來轉去,首先這個語法的目的是為了解決重復性,當數據庫中存在某個記錄時,執行這條語句會更新它,而不存在這條記錄時,會插入它。

相當於 先判斷一條記錄是否存在,存在則update,否則insert。其語法是:

INSERT INTO tablename(field1,field2, field3, ...) VALUES(value1, value2, value3, ...) ON DUPLICATE KEY UPDATE field1=value1,field2=value2, field3=value3, ...;

tablename是表名,field1,field2,field3等是字段名稱,value1,value2,value3等是字段值。

例如:

INSERT INTO t_stock_chg(f_market, f_stockID, f_name) VALUES(‘SH‘, ‘600000‘, ‘白雲機場‘) ON DUPLICATE KEY UPDATE f_market=‘SH‘, f_name=‘浦發銀行‘;

這條語句如果記錄不存在,插入該記錄;存在將f_market改為SH,f_name改為浦發銀行。現在有個問題是:這條語句判斷該條記錄是否存在的標準是什麽?由於同一個值是可以同時出現在多個記錄中的,所以必須有個字段是唯一不能重復的。

規則是這樣的:如果你插入的記錄導致一個UNIQUE索引或者primary key(主鍵)出現重復,那麽就會認為該條記錄存在,則執行update語句而不是insert語句,反之,則執行insert語句而不是更新語句。所以 ON DUPLICATE KEY UPDATE是不能寫where條件的,例如如下語法是錯誤的:

INSERT INTO t_stock_chg(f_market, f_stockID, f_name) VALUES(‘SH‘, ‘600000‘, ‘白雲機場‘) ON DUPLICATE KEY UPDATE f_market=‘SH‘, f_name=‘浦發銀行‘ WHERE f_stockID=‘600000‘;

因為由UNIQUE索引或者主鍵保證唯一性,不需要WHERE子條件。所以上面的INSERT INTO t_stock_chg(f_market, f_stockID, f_name) VALUES(‘SH‘, ‘600000‘, ‘白雲機場‘) ON DUPLICATE KEY UPDATE f_market=‘SH‘, f_name=‘浦發銀行‘;中f_stockID就是唯一主鍵。

這裏特別需要註意的是:如果行作為新記錄被插入,則受影響行的值為1;如果原有的記錄被更新,則受影響行的值為2,如果更新的數據和已有的數據一模一樣,則受影響的行數是0,這意味著不會去更新,也就是說即使你有的時間戳是自動記錄最後一次的更新時間,這個時間戳也不會變動。例如:

  1. CREATE TABLE `t_stock_chg` (
  2. `f_market` varchar(64) NOT NULL COMMENT ‘市場‘,
  3. `f_stockID` varchar(10) NOT NULL DEFAULT ‘‘ COMMENT ‘股票代碼‘,
  4. `f_updatetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘插入時間戳‘,
  5. `f_name` varchar(16) DEFAULT NULL COMMENT ‘股票名稱‘,
  6. PRIMARY KEY (`f_market`,`f_stockID`)
  7. ) ENGINE=MyISAM DEFAULT CHARSET=utf8

這裏的字段f_updatetime每次在更新數據時會自動更新,但是如果記錄中存在某條數據,後來又更新它,而更新的數據和原數據一模一樣,那麽這個字段也不會更新,仍然是上一次的時間。此時INSERT ... ON DUPLICATE KEY UPDATE影響行數是0。

mysql INSERT ... ON DUPLICATE KEY UPDATE語句