本文介绍 OceanBase 数据库 MySQL 模式下插入数据时提示重复的输入并报 ERROR 1062 错误的处理方法。
问题现象
向有主键的表 t_insert 中插入数据时,显示主键值重复。
obclient> SELECT * FROM t_insert;
+----+------+-------+---------------------+
| id | name | value | gmt_create |
+----+------+-------+---------------------+
| 1 | CN | 10001 | 2022-10-12 15:17:17 |
| 2 | US | 10002 | 2022-10-12 16:29:16 |
| 3 | EN | 10003 | 2022-10-12 16:29:26 |
+----+------+-------+---------------------+
3 rows in set
obclient> INSERT INTO t_insert(id, name, value) VALUES (3,'UK', 10003),(4, 'JP', 10004);
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'
该报错信息对应的错误码信息如下:
错误码:ERROR 1062
OceanBase 错误码:5024
兼容 MySQL 错误码:1062
可能原因
向表中插入数据时,如果表上有唯一性约束,再插入相同的记录时,系统就会报错。
解决方法
请参考以下两种方法解决冲突。
方法一:通过 INSERT IGNORE INTO 语句避免约束冲突,IGNORE 关键字可以忽略由于约束冲突导致的 INSERT 失败的影响。
在
t_insert表插入数据时添加IGNORE关键字。obclient> SELECT * FROM t_insert; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 10001 | 2022-10-12 15:17:17 | | 2 | US | 10002 | 2022-10-12 16:29:16 | | 3 | EN | 10003 | 2022-10-12 16:29:26 | +----+------+-------+---------------------+ 3 rows in set obclient> INSERT IGNORE INTO t_insert(id, name, value) VALUES (3,'UK', 10003),(4, 'JP', 10004); Query OK, 1 row affected再次查看
t_insert表的数据。可以看到,与主键值相同的记录被丢弃,与主键值不同的记录插入成功。obclient> SELECT * FROM t_insert; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 10001 | 2022-10-12 15:17:17 | | 2 | US | 10002 | 2022-10-12 16:29:16 | | 3 | EN | 10003 | 2022-10-12 16:29:26 | | 4 | JP | 10004 | 2022-10-12 17:02:52 | +----+------+-------+---------------------+ 4 rows in set
方法二:通过 INSERT INTO ON DUPLICATE KEY UPDATE 避免约束冲突,可以指定对重复主键或唯一键的后续处理,以下示例对冲突行内容进行了更新。
说明
- 指定
ON DUPLICATE KEY UPDATE column_name = expr:当要插入的主键或唯一键有重复值时,可以使用column_name = expr赋值语句来更新表中冲突行的数据。column_name = expr赋值语句可以为冲突行赋某一列或几列的值。赋多列值时,列与列之间用逗号分隔。 - 不指定
ON DUPLICATE KEY UPDATE column_name = expr:当要插入的主键或唯一键有重复值时,系统会报错。
在
t_insert表插入数据时通过INSERT INTO ON DUPLICATE KEY UPDATE避免约束冲突。obclient> SELECT * FROM t_insert; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 10001 | 2022-10-12 15:17:17 | | 2 | US | 10002 | 2022-10-12 16:29:16 | | 3 | EN | 10003 | 2022-10-12 16:29:26 | +----+------+-------+---------------------+ 3 rows in set obclient> INSERT INTO t_insert(id, name, value) VALUES (3,'UK', 10003),(4, 'JP', 10004) ON DUPLICATE KEY UPDATE name=VALUES(name); Query OK, 1 row affected再次查看
t_insert表的数据。可以看到,与主键值相同的记录被更新,与主键值不同的记录插入成功。obclient> select * from t_insert; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 10001 | 2022-10-12 15:17:17 | | 2 | US | 10002 | 2022-10-12 16:29:16 | | 3 | UK | 10003 | 2022-10-12 16:29:26 | | 4 | JP | 10004 | 2022-10-12 18:04:32 | +----+------+-------+---------------------+ 4 rows in set