首批通过分布式安全可靠测评,为关键业务系统打造
插入数据
更新时间:2026-02-10 15:41:22
表创建后,可以使用 INSERT 语句或其他语句向表中插入行记录。本文介绍了相关语句的使用方法和示例。
数据插入准备
在插入数据前,请确认以下事项:
请确认您已连接到数据库的 MySQL 租户,连接数据库的操作请参见 连接方式概述。
说明
当前登录租户所属的租户模式可以由
sys租户通过查询oceanbase.DBA_OB_TENANTS视图进行确认。请确认您已拥有待操作的表的
INSERT权限,查看当前用户权限的相关操作请参见 查看用户权限。如果不具备该权限,请联系管理员为您授权,用户授权的相关操作请参见 直接授予权限。
使用 INSERT INTO 语句插入数据
请使用 INSERT 语句,再参考下面的建议,向表中插入数据。
INSERT INTO 语句的语法格式如下:
INSERT INTO table_name (list_of_columns) VALUES (list_of_values);
| 参数 | 是否必填 | 描述 |
|---|---|---|
| table_name | 是 | 指定需要插入数据的表 |
| (list_of_columns) | 否 | 指定表中需要插入数据的列 |
| (list_of_values) | 是 | list_of_columns 提到的列的对应值,必须一一对应。 |
插入数据建议
插入数据前,建议了解表的所有列信息,包括列类型、有效值以及是否允许为 NULL 等。
查看列信息可以通过
DESC语句查看。obclient [test]> DESC test; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | col1 | int(11) | NO | | NULL | | | col2 | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 2 rows in set如果列属性为
NOT NULL如果列属性有默认值,则可以在插入时不指定该列的值,系统会在该列上插入默认值。
如果列属性无默认值,则插入时必须指定该列的值。
如果列属性为
NULL,则可以在插入时不指定该列的值,系统会在该列上插入一个NULL值。
插入数据前,建议了解表上列的约束定义情况,避免插入数据时报错。
NOT NULL、PRIMARY KEY约束、UNIQUE约束均可以通过DESC语句查看,FOREIGN KEY、CHECK约束可以通过查询information_schema.TABLE_CONSTRAINTS视图进行查看。
插入单行数据
通过 INSERT 语句可以插入单行数据。如果需要插入多条记录,可以执行多个单行插入语句来实现。如果需要批量插入,可参考 批量插入多行数据 进行操作。
假设待插入数据的表信息如下:
obclient [test]> CREATE TABLE t_insert(
id int NOT NULL PRIMARY KEY,
name varchar(10) NOT NULL,
value int,
gmt_create DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
Query OK, 0 rows affected
其中,表的 id 列、name 列不能为空,且 id 列为主键列,满足唯一性约束要求,不能有重复的值;gmt_create 列指定了默认值。
示例 1:使用多个单行插入语句插入多行数据。
由于 gmt_create 列指定了默认值,在插入数据时可以不指定默认值。
obclient [test]> INSERT INTO t_insert(id, name, value)
VALUES (1,'CN',10001);
Query OK, 2 rows affected
obclient [test]> INSERT INTO t_insert(id, name, value)
VALUES(2,'US', 10002);
Query OK, 2 rows affected
注意,如果 gmt_create 列未指定默认值,则在插入数据时,必须指定值,语句如下。
obclient [test]> INSERT INTO t_insert(id, name, value, gmt_create)
VALUES (3,'EN', 10003, current_timestamp ());
Query OK, 1 row affected
批量插入多行数据
在插入数据时,如果要插入多条记录,也可以用一个 INSERT 语句包含多个 VALUES 来批量插入。单个多行插入语句比多个单行插入语句要快。
示例 1 中的操作,又可以通过以下语句来完成。
示例 2:批量插入多行数据。
obclient [test]> INSERT INTO t_insert(id, name, value)
VALUES (1,'CN',10001),(2,'US', 10002);
Query OK, 2 rows affected
此外,当需要备份表数据或者将一个表的全部记录拷贝到另一个表时,可以使用查询语句 INSERT INTO ... SELECT ... FROM 充当 INSERT 的 values 子句进行批量插入。
示例 3:将表 t_insert 中的全部数据备份到 t_insert_bak 表中。
obclient [test]> 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 [test]> CREATE TABLE t_insert_bak(
id number NOT NULL PRIMARY KEY,
name varchar(10) NOT NULL,
value number,
gmt_create DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
Query OK, 0 rows affected
obclient [test]> INSERT INTO t_insert_bak SELECT * FROM t_insert;
Query OK, 2 rows affected
obclient [test]> SELECT * FROM t_insert_bak;
+----+------+-------+---------------------+
| 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 [test]> INSERT INTO t_insert(id, name, value) VALUES (3,'UK', 10003),(4, 'JP', 10004);
ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY'
该报错可以通过 INSERT IGNORE INTO 语句或 INSERT INTO ON DUPLICATE KEY UPDATE 语句来避免。
示例:
通过
INSERT IGNORE INTO语句避免约束冲突时,IGNORE关键字可以忽略由于约束冲突导致的INSERT失败的影响。obclient [test]> INSERT IGNORE INTO t_insert(id, name, value) VALUES (3,'UK', 10003),(4, 'JP', 10004); Query OK, 1 row affected obclient [test]> 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 IGNORE INTO语句,(3,'UK', 10003)这一行数据插入失败,但系统未再报错。通过
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:当要插入的主键或唯一键有重复时,插入数据时,系统会报错。
obclient [test]> INSERT INTO t_insert(id, name, value) VALUES (3,'UK', 10003),(5, 'CN', 10005) ON DUPLICATE KEY UPDATE name = VALUES(name); Query OK, 1 row affected obclient [test]> SELECT * FROM t_insert; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 10001 | 2022-10-12 16:29:16 | | 2 | US | 10002 | 2022-10-12 15:17:17 | | 3 | UK | 10003 | 2022-10-12 16:29:26 | | 4 | JP | 10004 | 2022-10-12 17:02:52 | | 5 | CN | 10005 | 2022-10-12 17:27:46 | +----+------+-------+---------------------+ 5 rows in set示例中,
ON DUPLICATE KEY UPDATE name = VALUES(name)即表示当插入的数据与表中的主键值有重复时,将表中冲突行原数据中(3,'EN', 10003)的name列的值更新为当前待插入的name列的数据。其他不冲突的行,则正常插入。- 指定
使用 INSERT OVERWRITE SELECT 语句插入数据
INSERT OVERWRITE SELECT 语句用于将查询结果替换表中的现有数据,即将查询出的数据覆盖写到目标表中。
该语句语法格式如下:
INSERT [/*+PARALLEL(N)*/] OVERWRITE table_name select_stmt;
| 参数 | 描述 |
|---|---|
| PARALLEL(N) | 可选项,指定覆盖写操作的并行执行程度。若未指定,默认采用的并行度为 2。 |
| table_name | 指定要插入的表名。 |
| select_stmt | 指定 SELECT 子句。有关查询语句的详细信息,参见 SELECT 语句。 |
INSERT OVERWRITE SELECT 使用限制
- 该语句无法在多行事务中操作。因此,为确保操作顺利进行,需先执行
SET autocommit = on;命令开启自动提交事务。 - 对写入表加表锁,不允许对同一张表并发的发起任何 DDL 操作,并发发起的 DML 操作会等待表锁释放直至超时,允许在操作期间对表进行查询。
- 当前版本仅支持对整个表进行数据覆盖插入,而不支持针对表的特定分区执行分区级别的数据覆盖操作。
- 该语句操作的源数据和目标表的列数目必须严格匹配,否则会报错。
- 该语句数据写入操作是全量旁路导入方式,所以操作受全量旁路导入功能限制。有关旁路导入的信息,参见 使用 INSERT INTO SELECT 语句旁路导入数据 中的 使用限制 章节。
- 该语句指定旁路导入 Hint 会报错。
- 受 PDML(Parallel Data Manipulation Language,并行数据操纵语言)框架限制,PDML 不支持的场景无法导入数据,
INSERT OVERWRITE SELECT会报错 not supported。有关并行 DML 的详细信息,参见 并行 DML。
INSERT OVERWRITE SELECT 示例
创建两个测试表:
source_tbl1作为数据源,target_tbl1作为目标表。CREATE TABLE source_tbl1 (col1 INT, col2 VARCHAR(20), col3 INT);CREATE TABLE target_tbl1 (col1 INT, col2 VARCHAR(20), col3 INT);向表
source_tbl1中插入示例数据。INSERT INTO source_tbl1 VALUES (1, 'A1', 30),(2, 'B2', 25),(3, 'C3', 22);向表
target_tbl1中插入示例数据。INSERT INTO target_tbl1 VALUES (4, 'D4', 35),(5, 'E5', 28);查询表
target_tbl1中的数据。SELECT * FROM target_tbl1;返回结果如下:
+------+------+------+ | col1 | col2 | col3 | +------+------+------+ | 4 | D4 | 35 | | 5 | E5 | 28 | +------+------+------+ 2 rows in set使用
INSERT OVERWRITE SELECT语句,基于col3大于 25 从source_tbl1中筛选数据,并将这些数据插入到target_tbl1中,替换其原有内容。INSERT OVERWRITE target_tbl1 SELECT * FROM source_tbl1 WHERE col3 > 25;查看表
target_tbl1替换数据后的数据。SELECT * FROM target_tbl1;返回结果如下:
+------+------+------+ | col1 | col2 | col3 | +------+------+------+ | 1 | A1 | 30 | +------+------+------+ 1 row in set
使用 REPLACE INTO 语句插入数据
除了 INSERT 语句,当表中无数据记录,或者表中有数据记录但无主键或唯一键冲突时,还可以使用 REPLACE INTO 语句代替 INSERT 语句插入数据。REPLACE INTO 语句的详细语法及说明请参见 REPLACE。
示例:
创建
t_replace表后,使用REPLACE INTO语句插入数据。obclient [test]> CREATE TABLE t_replace( id int NOT NULL PRIMARY KEY , name varchar(10) NOT NULL , value int ,gmt_create timestamp NOT NULL DEFAULT current_timestamp ); Query OK, 0 rows affected obclient [test]> REPLACE INTO t_replace VALUES(1,'CN',2001, current_timestamp ()); Query OK, 1 row affected obclient [test]> SELECT * FROM t_replace; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 2001 | 2022-11-23 09:52:44 | +----+------+-------+---------------------+ 1 row in set在有数据记录的表
t_replace中,使用REPLACE INTO语句插入数据。obclient [test]> SELECT * FROM t_replace; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 2001 | 2022-03-22 16:13:55 | +----+------+-------+---------------------+ 1 row in set obclient [test]> REPLACE INTO t_replace values(2,'US',2002, current_timestamp ()); Query OK, 1 row affected obclient [test]> SELECT * FROM t_replace; +----+------+-------+---------------------+ | id | name | value | gmt_create | +----+------+-------+---------------------+ | 1 | CN | 2001 | 2022-11-23 09:52:44 | | 2 | US | 2002 | 2022-11-23 09:53:05 | +----+------+-------+---------------------+ 2 rows in set