插入数据
表创建后,可以使用 INSERT 语句或其他语句向表中插入行记录。本文介绍了相关语句的使用方法和示例。
数据插入准备
在插入数据前,请确认以下事项:
-
请确认您已连接到 seekdb,连接数据库的操作请参见 连接方式概述。
-
请确认您已拥有待操作的表的
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语句查看。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 语句可以插入单行数据。如果需要插入多条记录,可以执行多个单行插入语句来实现。如果需要批量插入,可参考 批量插入多行数据 进行操作。
假设待插入数据的表信息如下:
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 列指定了默认值,在插入数据时可以不指定默认值。
INSERT INTO t_insert(id, name, value)
VALUES (1,'CN',10001);
Query OK, 2 rows affected
INSERT INTO t_insert(id, name, value)
VALUES(2,'US', 10002);
Query OK, 2 rows affected
注意,如果 gmt_create 列未指定默认值,则在插入数据时,必须指定值,语句如下。
INSERT INTO t_insert(id, name, value, gmt_create)
VALUES (3,'EN', 10003, current_timestamp ());
Query OK, 1 row affected
批量插入多行数据
在插入数据时,如果要插入多条记录,也可以用一个 INSERT 语句包含多个 VALUES 来批量插入。单个多行插入语句比多个单行插入语句要快。
示例 1 中的操作,又可以通过以下语句来完成。
示例 2:批量插入多行数据。
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 表中。
SELECT * FROM t_insert;
+----+------+-------+---------------------+
| id | name | value | gmt_create |
+----+------+-------+---------------------+
| 1 | CN | 10001 | 2025-12-22 21:41:28 |
| 2 | US | 10002 | 2025-12-22 21:41:32 |
| 3 | EN | 10003 | 2025-12-22 21:41:43 |
+----+------+-------+---------------------+
3 rows in set
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
INSERT INTO t_insert_bak SELECT * FROM t_insert;
Query OK, 3 rows affected
SELECT * FROM t_insert_bak;
+----+------+-------+---------------------+
| id | name | value | gmt_create |
+----+------+-------+---------------------+
| 1 | CN | 10001 | 2025-12-22 21:41:28 |
| 2 | US | 10002 | 2025-12-22 21:41:32 |
| 3 | EN | 10003 | 2025-12-22 21:41:43 |
+----+------+-------+---------------------+
3 rows in set
避免唯一性约束冲突
当表上有唯一性约束的时候,插入相同的记录,数据库会报错。报错信息如下:
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失败的影响。INSERT IGNORE INTO t_insert(id, name, value)
VALUES (3,'UK', 10003),(4, 'JP', 10004);
Query OK, 1 row affected
SELECT * FROM t_insert;
+----+------+-------+---------------------+
| id | name | value | gmt_create |
+----+------+-------+---------------------+
| 1 | CN | 10001 | 2025-12-22 21:41:28 |
| 2 | US | 10002 | 2025-12-22 21:41:32 |
| 3 | EN | 10003 | 2025-12-22 21:41:43 |
| 4 | JP | 10004 | 2025-12-22 21:43:28 |
+----+------+-------+---------------------+
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:当要插入的主键或唯一键有重复时,插入数据时,系统会报错。
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
SELECT * FROM t_insert;
+----+------+-------+---------------------+
| id | name | value | gmt_create |
+----+------+-------+---------------------+
| 1 | CN | 10001 | 2025-12-22 21:41:28 |
| 2 | US | 10002 | 2025-12-22 21:41:32 |
| 3 | UK | 10003 | 2025-12-22 21:41:43 |
| 4 | JP | 10004 | 2025-12-22 21:43:28 |
| 5 | CN | 10005 | 2025-12-22 21:46:27 |
+----+------+-------+---------------------+
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 [(list_of_columns)] [PARTITION (partition_name, ...)] select_stmt;
| 参数 | 描述 |
|---|---|
| PARALLEL(N) | 可选项,指定覆盖写操作的并行执行程度。若未指定,默认采用的并行度为 2。 |
| table_name | 指定要插入的表名。 |
| list_of_columns | 指定表中需要插入数据的列。 |
| select_stmt | 指定 SELECT 子句。有关查询语句的详细信息,参见 SELECT 语句。 |
| partition_name | 插入表指定的分区名,同时插入多个分区时以逗号(,)分隔。 |
INSERT OVERWRITE 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
功能介绍
- 源表可以为分区表或非分区表,分区类型无要求。
- 支持目标表为一级或二级分区。
- 支持目标表有局部索引和 LOB。
- 可以指定目标表的全部或者部分分区,如果目标表有二级分区,则可以单独或混合指定一二级分区。
- 如果指定的目标表分区没有被任何来自源表的数据命中,则该分区数据会被清空(被空数据覆盖)。
- 分区级的
insert overwrite操作支持目标表最后一级分区为 Hash 或 Key 分区。
使用限制
- 指定的分区必须已经存在,否则会报错。
- 基于全量旁路导入,无需再添加
/*+ append */Hint,否则使用会报错。 - 该语句无法在多行事务中操作。因此,为确保操作顺利进行,需先执行
SET autocommit = on;命令开启自动提交事务。 - 如果来自源表的数据经过目标表的分区规则计算后,没有命中到指定的目标表分区中,则会报错分区不存在。
- 暂不支持目标表有自增列。
- 暂不支持目标表有全局索引或外键。
- 暂不支持目标表为外表。