通過INSERT ON DUPLICATE KEY UPDATE更新資料時,AnalyticDB for MySQL會首先嘗試在表中插入新行,如果新資料與已有資料的主鍵重複,則將更新同主鍵的資料。
AnalyticDB for MySQL會根據待寫入行是否存在選擇對應的執行語句,規則如下:
待寫入行不存在,則執行
INSERT插入新行,受影響的行數為1。待寫入行存在,則執行
UPDATE更新現有行,受影響的行數也為1。
注意事項
INSERT INTO ... ON DUPLICATE KEY UPDATE...只支援等值更新,不支援複雜運算式(包括算術運算式、條件運算式等)。在更新資料量較大或資料更新頻率高(超過100 QPS)的情境下,使用
INSERT ON DUPLICATE KEY UPDATE更新資料會導致CPU使用率顯著升高。建議您使用REPLACE INTO批次更新資料。詳情請參見REPLACE INTO。
文法
INSERT INTO table_name[(column_name[, …])]
[VALUES]
[(value_list[, …])]
ON DUPLICATE KEY UPDATE
c1 = v1,
c2 = v2,
...;樣本
本文所有樣本均基於student_course表,建表語句如下:
CREATE TABLE student_course(
id bigint,
user_id bigint,
nc_id varchar,
nc_user_id varchar,
nc_commodity_id varchar,
course_no varchar,
course_name varchar,
business_id varchar,
PRIMARY KEY(user_id)
) DISTRIBUTED BY HASH(user_id);使用如下語句插入一行資料:
INSERT INTO student_course (`id`, `user_id`, `nc_id`, `nc_user_id`, `nc_commodity_id`, `course_no`, `course_name`, `business_id`)
VALUES(277941, 11056941, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工業會計實戰V9.0--55', 'kuaiji')
ON DUPLICATE KEY UPDATE
course_name = '工業會計實戰V9.0--55',
business_id = 'kuaiji';執行SELECT * FROM student_course;語句,返回如下結果說明資料插入成功:
+-------+----------+---------------------+---------------------+---------------------+-----------+---------------------+------------+
| id | user_id | nc_id | nc_user_id | nc_commodity_id | course_no | course_name |business_id |
+-------+----------+---------------------+---------------------+---------------------+-----------+---------------------+------------+
|277941 | 11056941 | 1001EE1000000043G2T5|1001EE1000000043G2TO | 1001A5100000003YABO2| kckm303 | 工業會計實戰V9.0--55| kuaiji |
+-------+----------+---------------------+---------------------+---------------------+-----------+---------------------+------------+此時,需要再往student_course表中入一行新資料:
INSERT INTO student_course(`id`, `user_id`, `nc_id`, `nc_user_id`, `nc_commodity_id`, `course_no`, `course_name`, `business_id`)
VALUES(277942, 11056941, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工業會計實戰V9.0--66', 'kuaiji')
ON DUPLICATE KEY UPDATE
course_name = '工業會計實戰V9.0--66',
business_id = 'kuaiji';但由於新插入的資料中存在重複主鍵(即user_id與第一次插入的資料重複,均為11056941),因此執行上述語句後只會更新ON DUPLICATE KEY UPDATE子句中的course_name = '工業會計實戰V9.0--66',business_id = 'kuaiji'值,您可以執行SELECT * FROM student_course;語句來查看更新後的資料,返回結果如下:
+-------+----------+---------------------+---------------------+---------------------+-----------+---------------------+------------+
| id | user_id | nc_id | nc_user_id | nc_commodity_id | course_no | course_name |business_id |
+-------+----------+---------------------+---------------------+---------------------+-----------+---------------------+------------+
|277941 | 11056941 | 1001EE1000000043G2T5|1001EE1000000043G2TO | 1001A5100000003YABO2| kckm303 | 工業會計實戰V9.0--66| kuaiji |
+-------+----------+---------------------+---------------------+---------------------+-----------+---------------------+------------+常見問題
怎麼解決報錯`insert on duplicate key update` statement only support 'primitive value' and values() expr.
報錯原因:INSERT INTO ... ON DUPLICATE KEY UPDATE...只支援基本值賦值(下文例1)或VALUES()賦值(下文例2),不支援複雜運算式(例如算術運算式、條件運算式)和函數。當ON DUPLICATE KEY UPDATE中使用了複雜運算式或函數時,會出現該報錯。
解決辦法:修改SQL語句,在ON DUPLICATE KEY UPDATE中使用基本值賦值或VALUES()賦值。
例1:基本值賦值。
INSERT INTO student_course (`id`, `user_id`, `nc_id`, `nc_user_id`, `nc_commodity_id`, `course_no`, `course_name`, `business_id`)
VALUES(277941, 11056941, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工業會計實戰V9.0--55', 'kuaiji')
ON DUPLICATE KEY UPDATE
course_name = '工業會計實戰V9.0--55',
business_id = 'kuaiji';例2:VALUES()賦值。
INSERT INTO student_course (`id`, `user_id`, `nc_id`, `nc_user_id`, `nc_commodity_id`, `course_no`, `course_name`, `business_id`)
VALUES(277941, 11056941, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工業會計實戰V9.0--55', 'kuaiji')
ON DUPLICATE KEY UPDATE
course_name = VALUES(course_name),
business_id = VALUES(business_id);怎麼解決報錯Error : Field 'xxxx' doesn't have a default value?
原因:在建表時,已指定該列資料不為空白(即column_name column_datatype NOT NULL),但未指定該列的預設值。在執行INSERT INTO ... ON DUPLICATE KEY UPDATE...插入資料時,未向該列插入資料,且該列無預設值,導致出現上述報錯。
解決方案:以下兩種方法任選一種即可。
修改
INSERT INTO ... ON DUPLICATE KEY UPDATE...語句,向指定列插入具體的資料。修改表結構,給指定列增加預設值,然後重新執行
INSERT INTO ... ON DUPLICATE KEY UPDATE...語句。
INSERT ON DUPLICATE KEY UPDATE是否支援批量插入資料?
支援。使用INSERT ON DUPLICATE KEY UPDATE批量插入資料時,您可以使用 VALUES 子句提供多組值,並在 ON DUPLICATE KEY UPDATE 子句指定如何處理衝突。
例如,在student_course表中批量插入3條資料:
INSERT INTO student_course(`id`, `user_id`, `nc_id`, `nc_user_id`, `nc_commodity_id`, `course_no`, `course_name`, `business_id`)
VALUES(277943, 11056941, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工業會計實戰V9.0--77', 'kuaiji'),
(277944, 11056943, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工業會計實戰V9.0--88', 'kuaiji'),
(277945, 11056944, '1001EE1000000043G2T5', '1001EE1000000043G2TO', '1001A5100000003YABO2', 'kckm303', '工業會計實戰V9.0--99', 'kuaiji')
ON DUPLICATE KEY UPDATE
course_name = VALUES(course_name),
business_id = VALUES(business_id);