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);
怎么解决报错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);