INSERT ON DUPLICATE KEY UPDATE
通过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);
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);