1. 程式人生 > 其它 >SQL主鍵衝突或者唯一索引衝突更新duplicate key update ... values()

SQL主鍵衝突或者唯一索引衝突更新duplicate key update ... values()

SQL主鍵衝突或者唯一索引衝突更新duplicate key update ... values()
**說明:
1. on duplicate key update 含義:
1)如果在INSERT語句末尾指定了 on duplicate key update,
並且插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重複值,
則在出現重複值的行執行UPDATE;
2)如果不會導致唯一值列重複的問題,則插入新行。

2. values(col_name)函式只是取當前插入語句中的插入值,並沒有累加功能。
如:count = values(count) 取前面 insert into 中的 count 值,並更新
當有多條記錄衝突,需要插入時,前面的更新值都被最後一條記錄覆蓋,
所以呈現出取最後一條更新的現象。
如:count 
= count + values(count) 依然取前面 insert into 中的 count 值, 並與原記錄值相加後更新回資料庫,這樣,當多條記錄衝突需要插入時, 就實現了不斷累加更新的現象。 注:insert into ... on duplicate key update ... values() 這個語句 儘管在衝突時執行了更新,並沒有插入,但是發現依然會佔用 id 序號(自增), 出現很多丟失的 id 值,可參看下面案例

----《百度百科--MySQL函式》
函式 VALUES(col_name)
函式使用說明:在一個 INSERT … ON DUPLICATE KEY UPDATE … 語句中,你可以在 UPDATE 子句中使用 VALUES(col_name ) 函式,用來訪問來自該語句的 INSERT 部分的列值。換言之,UPDATE 子句中的 VALUES(col_name ) 訪問需要被插入的 col_name 的值 , 並不會發生重複鍵衝突。這個函式在多行插入中特別有用。 VALUES() 函式只在 INSERT ... UPDATE 語句中有意義,而在其它情況下只會返回 NULL。

**案例:
0. 建立案例表 word_count_0626(單詞計數表)
  use test;
  CREATE TABLE IF NOT EXISTS word_count_0626 (
      id int(11) NOT NULL AUTO_INCREMENT,
      word varchar(64) NOT NULL,
      count int(11) DEFAULT 0,
      date date NOT NULL,
      PRIMARY KEY (id),
      UNIQUE KEY word (word, date)  // (word,date) 兩欄位組合唯一
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 注:curdate() 為 "2019-06-26" 1. 執行第一次:(首次資料庫表中沒有資料,正常插入) insert into word_count_0626 (word, count, date) values ('a',5,curdate()) on duplicate key update count=values(count); # 結果顯示: id word count date 1 a 5 2019-06-26 2. 執行第二次:(與第一次的唯一(word,date)衝突,執行更新) insert into word_count_0626 (word, count, date) values ('a',6,curdate()) on duplicate key update count=values(count); # 結果顯示: id word count date 1 a 6 2019-06-26 (更新) 3. 執行第三次: insert into word_count_0626 (word, count, date) values ('a',6,curdate()-1), // 取前一天,不會衝突 ('a',7,curdate()) // 衝突 on duplicate key update count=values(count); # 結果顯示: id word count date 1 a 7 2019-06-26 (更新) 3 a 6 2019-06-25 (新插入) 4. 執行第四次:(更新衝突的最後一條插入值) insert into word_count_0626 (word, count, date) values ('a',2,curdate()), // 衝突 ('a',1,curdate()) // 衝突 on duplicate key update count=values(count); # 結果顯示: id word count date 1 a 1 2019-06-26 (更新最後一條插入值) 3 a 6 2019-06-25 (不變) 5. 執行第五次:(更新衝突的累加插入值) insert into word_count_0626 (word, count, date) values ('a',2,curdate()), ('a',1,curdate()) on duplicate key update count=count+values(count); // 實現每行累加 # 結果顯示: id word count date 1 a 4 2019-06-26 3 a 6 2019-06-25 6. 執行第六次:(無衝突插入,觀察 id 鍵值,出現了很多丟失,id 直接跳到了 9) insert into word_count_0626 (word, count, date) values ('b',2,curdate()) on duplicate key update count=count+values(count); # 結果顯示: id word count date 1 a 4 2019-06-26 3 a 6 2019-06-25 9 b 2 2019-06-26

轉載自:MySQL中 insert into ... on duplicate key update ... values() 的使用筆記