---
title: "插入数据 - OceanBase 数据库 V4.6.0 | OceanBase 文档中心"
description: 插入数据 表创建后，可以使用 INSERT 语句或其他语句向表中插入行记录。本文介绍了相关语句的使用方法和示例。 数据插入准备 在插入数据前，请确认以下事项： 请确认您已连接到数据库的 Oracle 租户，连接数据库的操作请参见 连接方式概述 。 说明 当前登录租户所属的租户模式可以由 sys 租户通过查询 ocea…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.6.0

# 插入数据

更新时间：2026-07-04 20:31:12

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.6.0/zh-CN/300.develop/200.application-development-of-oracle-mode/400.write-data-of-oracle-mode/100.insert-data-of-oracle-mode-in-develop.md)  

表创建后，可以使用 `INSERT` 语句或其他语句向表中插入行记录。本文介绍了相关语句的使用方法和示例。

## 数据插入准备

在插入数据前，请确认以下事项：

- 请确认您已连接到数据库的 Oracle 租户，连接数据库的操作请参见 [连接方式概述](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682578)。

  #### 说明

  当前登录租户所属的租户模式可以由 `sys` 租户通过查询 `oceanbase.DBA_OB_TENANTS` 视图进行确认。
 - 请确认您已拥有待操作表的 `INSERT` 权限，查看当前用户权限的相关操作请参见 [查看用户权限](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005685761)。如果不具备该权限，请联系管理员为您授权，用户授权的相关操作请参见 [直接授予权限](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005685760)。

## 使用 INSERT INTO 语句插入数据

请使用 [INSERT](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005687602) 语句，再参考下面的建议，向表中插入数据。

`INSERT INTO` 语句语法格式如下：

```sql
INSERT INTO table_name [(list_of_columns)] VALUES (list_of_values);

```

| 参数 | 是否必填 | 描述 |
| --- | --- | --- |
| table_name | 是 | 指定需要插入数据的表 |
| (list_of_columns) | 否 | 指定表中需要插入数据的列 |
| (list_of_values) | 是 | list_of_columns 提到的列的对应值，必须一一对应。 |

### 插入数据建议

- 插入数据前，建议了解表的所有列信息，包括列类型、有效值以及是否允许为 NULL 等。

  查看列信息可以通过 `DESC` 语句查看。

  ```shell
  obclient [SYS]> DESC ordr;
  +-------+--------------+------+-----+---------+-------+
  | FIELD | TYPE         | NULL | KEY | DEFAULT | EXTRA |
  +-------+--------------+------+-----+---------+-------+
  | C1    | NUMBER       | YES  | NULL | NULL    | NULL  |
  | C2    | VARCHAR2(50) | YES  | NULL | NULL    | NULL  |
  +-------+--------------+------+-----+---------+-------+
  2 rows in set

  ```

     - 如果列属性为 `NOT NULL`

           - 如果列属性有默认值，则可以在插入时不指定该列的值，系统会在该列上插入默认值。
           - 如果列属性无默认值，则插入时必须指定该列的值。
     - 如果列属性为 `NULL`，则可以在插入时不指定该列的值，系统会在该列上插入一个 `NULL` 值。
 - 插入数据前，建议了解表上列的约束定义情况，避免插入数据时报错。

  `NOT NULL`、`PRIMARY KEY` 约束、`UNIQUE` 约束均可以通过 `DESC` 语句查看，`FOREIGN KEY`、`CHECK` 约束可以通过查询 `ALL_CONSTRAINTS`、`DBA_CONSTRAINTS` 或 `USER_CONSTRAINTS` 视图进行查看。

### 插入单行数据

通过 `INSERT` 语句可以插入单行数据。如果需要插入多条记录，可以执行多个单行插入语句来实现。如果需要批量插入，可参考 [批量插入多行数据](#批量插入多行数据) 进行操作。

假设待插入数据的表信息如下：

```shell
obclient [SYS]> CREATE TABLE t_insert(
    id number NOT NULL PRIMARY KEY,
    name varchar(10) NOT NULL,
    value number,
    gmt_create DATE NOT NULL DEFAULT sysdate
 );
Query OK, 0 rows affected

```

其中，表的 `id` 列、`name` 列不能为空，且 `id` 列为主键列，满足唯一性约束要求，不能有重复的值；`gmt_create` 列指定了默认值。

示例 1：使用多个单行插入语句插入多行数据。

由于 `gmt_create` 列指定了默认值，在插入数据时可以不指定默认值。

```shell
obclient [SYS]> INSERT INTO t_insert(id, name, value)
VALUES (1,'CN',10001);
Query OK, 2 rows affected

obclient [SYS]> INSERT INTO t_insert(id, name, value)
VALUES(2,'US', 10002);
Query OK, 2 rows affected

```

注意，如果 `gmt_create` 列未指定默认值，则在插入数据时，必须指定值，语句如下。

```shell
obclient [SYS]> INSERT INTO t_insert(id, name, value, gmt_create)
 VALUES (3,'EN', 10003, sysdate);
Query OK, 1 row affected

```

### 批量插入多行数据

在插入数据时，如果要插入多条记录，也可以用一个 `INSERT` 语句包含多个 `VALUES` 来批量插入。单个多行插入语句比多个单行插入语句要快。

示例 1 中的操作，又可以通过以下语句来完成。

示例 2：批量插入多行数据。

```shell
obclient [SYS]> 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` 表中。

```shell
obclient [SYS]> SELECT * FROM t_insert;
+----+------+-------+------------+
| ID | NAME | VALUE | GMT_CREATE |
+----+------+-------+------------+
|  1 | CN   | 10001 | 31-OCT-22  |
|  2 | US   | 10002 | 31-OCT-22  |
|  3 | EN   | 10003 | 31-OCT-22  |
+----+------+-------+------------+
3 rows in set

obclient [SYS]> CREATE TABLE t_insert_bak(
    id number NOT NULL PRIMARY KEY,
    name varchar(10) NOT NULL,
    value number,
    gmt_create DATE NOT NULL DEFAULT sysdate
 );
Query OK, 0 rows affected

obclient [SYS]> INSERT INTO t_insert_bak SELECT * FROM t_insert;
Query OK, 2 rows affected
Records: 3  Duplicates: 0  Warnings: 0

obclient [SYS]> SELECT * FROM t_insert_bak;
+----+------+-------+------------+
| ID | NAME | VALUE | GMT_CREATE |
+----+------+-------+------------+
|  1 | CN   | 10001 | 31-OCT-22  |
|  2 | US   | 10002 | 31-OCT-22  |
|  3 | EN   | 10003 | 31-OCT-22  |
+----+------+-------+------------+
3 rows in set

```

## 使用 INSERT OVERWRITE SELECT 语句插入数据

`INSERT OVERWRITE SELECT` 语句用于将查询结果替换表中的现有数据，即将查询出的数据覆盖写到目标表中。该操作保证原子性，即执行过程中遇到任何异常，操作会整体回滚。

该语句语法格式如下：

```sql
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` 子句。有关查询语句的详细信息，参见 [SIMPLE SELECT](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005688259)。 |
| partition_name | 插入表指定的分区名，同时插入多个分区时以逗号（,）分隔。 |

### INSERT OVERWRITE SELECT 使用限制

#### 表级 INSERT OVERWRITE SELECT 使用限制

- 该语句无法在多行事务中操作。因此，为确保操作顺利进行，需先执行 `SET autocommit = on;` 命令开启自动提交事务。
 - 对写入表加表锁，不允许对同一张表并发的发起任何 DDL 操作，并发发起的 DML 操作会等待表锁释放直至超时，允许在操作期间对表进行查询。
 - 该语句操作的源数据和目标表覆盖写的列数目必须严格匹配，否则会报错。
 - 该语句数据写入操作是全量旁路导入方式，所以操作受全量旁路导入功能限制。有关旁路导入的信息，参见 [使用 INSERT INTO SELECT 语句旁路导入数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000006277725) 中的 **使用限制** 章节。
 - 该语句指定旁路导入 Hint 会报错。
 - 受 PDML（Parallel Data Manipulation Language，并行数据操纵语言）框架限制，PDML 不支持的场景无法导入数据，`INSERT OVERWRITE SELECT` 会报错 not supported。有关并行 DML 的详细信息，参见 [并行 DML](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005685104)。

#### 分区级 INSERT OVERWRITE SELECT

**功能介绍**

- 源表可以为分区表或非分区表，分区类型无要求。
 - 支持目标表为一级或二级分区。
 - 支持目标表有局部索引和 LOB。
 - 可以指定目标表的全部或者部分分区，如果目标表有二级分区，则可以单独或混合指定一二级分区。
 - 如果来自源表的数据经过目标表的分区规则计算后，没有命中到指定的目标表分区中，则会报错分区不存在。
 - 如果指定的目标表分区没有被任何来自源表的数据命中，则该分区数据会被清空（被空数据覆盖）。
 - 分区级的 `insert overwrite` 操作支持目标表最后一级分区为 Hash 或 Key 分区。

**使用限制**

- 指定的分区必须已经存在，否则会报错。
 - 基于全量旁路导入，无需再添加 `/*+ append */` Hint，否则使用会报错。
 - 该语句无法在多行事务中操作。因此，为确保操作顺利进行，需先执行 `SET autocommit = on;` 命令开启自动提交事务。
 - 暂不支持目标表有有 identity 列。
 - 暂不支持目标表有全局索引或外键。
 - 暂不支持目标表为外表。

### INSERT OVERWRITE SELECT 示例

#### 示例一

1. 执行下面 SQL 开启自动提交事务。

   ```sql
   SET autocommit = on;

   ```
 2. 创建两个测试表：`source_tbl1` 作为数据源，`target_tbl1` 作为目标表。

   ```sql
   CREATE TABLE source_tbl1 (col1 INT, col2 VARCHAR2(20), col3 INT);

   ```

   ```sql
   CREATE TABLE target_tbl1 (col1 INT, col2 VARCHAR2(20), col3 INT);

   ```
 3. 向表 `source_tbl1` 中插入示例数据。

   ```sql
   INSERT INTO source_tbl1 VALUES (1, 'A1', 30),(2, 'B2', 25),(3, 'C3', 22);

   ```
 4. 向表 `target_tbl1` 中插入示例数据。

   ```sql
   INSERT INTO target_tbl1 VALUES (4, 'D4', 35),(5, 'E5', 28);

   ```
 5. 查询表 `target_tbl1` 中的数据。

   ```sql
   SELECT * FROM target_tbl1;

   ```

   返回结果如下：

   ```shell
   +------+------+------+
   | COL1 | COL2 | COL3 |
   +------+------+------+
   |    4 | D4   |   35 |
   |    5 | E5   |   28 |
   +------+------+------+
   2 rows in set

   ```
 6. 使用 `INSERT OVERWRITE SELECT` 语句，基于 `col3` 大于 25 从 `source_tbl1` 中筛选数据，并将这些数据插入到 `target_tbl1` 中，替换其原有内容。

   ```sql
   INSERT OVERWRITE target_tbl1 SELECT * FROM source_tbl1 WHERE col3 > 25;

   ```
 7. 查看表 `target_tbl1` 替换数据后的数据。

   ```

   返回结果如下：

   ```shell
   +------+------+------+
   | COL1 | COL2 | COL3 |
   +------+------+------+
   |    1 | A1   |   30 |
   +------+------+------+
   1 row in set

   ```

#### 示例二

分区级 `INSTER OVERWRITE PARTITION` 使用示例：

   ```sql
   obclient [SYS]> SET autocommit = on;

   ```
 2. 执行下面 SQL 创建分区表 `t1_ins_overwrt`。

   ```sql
   obclient [SYS]> create table t1_ins_overwrt (c1 int primary key, c2 int) partition by range(c1)(
          partition p0 values less than(10),
          partition p1 values less than(20),
          partition p2 values less than(30),
          partition p3 values less than (MAXVALUE)
        );
   Query OK, 0 rows affected (0.223 sec)

   ```
 3. 执行下面 SQL 创建分区表 `t2_ins_overwrt`。

   ```sql
   obclient [SYS]> create table t2_ins_overwrt (c1 int primary key, c2 int) partition by range(c1)(
          partition p0 values less than(10),
          partition p1 values less than(20),
          partition p2 values less than(30),
          partition p3 values less than (MAXVALUE)
        );
   Query OK, 0 rows affected (0.092 sec)

   ```
 4. 分别向两张表中插入几条数据。

   ```sql
   obclient [SYS]> insert into t1_ins_overwrt values (12, 20), (34, 40), (45, 50);
   Query OK, 3 rows affected (0.002 sec)
   Records: 3  Duplicates: 0  Warnings: 0

   obclient [SYS]> insert into t2_ins_overwrt values (3, 60), (8, 80), (17, 170), (26, 260), (29, 290), (142, 1420);
   Query OK, 6 rows affected (0.003 sec)
   Records: 6  Duplicates: 0  Warnings: 0

   ```
 5. 分别查询两张表中 P1 分区的数据。

   ```sql
   obclient [SYS]> select * from t1_ins_overwrt partition(p1);
   +------+------+
   | C1   | C2   |
   +------+------+
   |   12 |   20 |
   +------+------+
   1 row in set (0.006 sec)

   obclient [SYS]> select * from t2_ins_overwrt partition(p1);
   +------+------+
   | C1   | C2   |
   +------+------+
   |   17 |  170 |
   +------+------+
   1 row in set (0.007 sec)

   ```
 6. 执行如下 SQL 将 `t1_ins_overwrt` 表中 p1 分区的数据插入到 `t2_ins_overwrt` 表指定的分区 p1中。

   ```sql
   obclient [SYS]> insert overwrite t2_ins_overwrt partition(p1) select * from t1_ins_overwrt partition(p1);
   Query OK, 3 rows affected (1.360 sec)
   Records: 3  Duplicates: 0  Warnings: 0

   ```
 7. 查询 `t2_ins_overwrt` 表，发现 p1 分区的数据被覆盖了。

   ```sql
   obclient [SYS]> SELECT * FROM t2_ins_overwrt partition(p1);
   +------+------+
   | C1   | C2   |
   +------+------+
   |   12 |   20 |
   +------+------+
   1 row in set (0.020 sec)

   ```

#### 示例三

1. 创建分区的表 `tbl1`。

   ```shell
   obclient [SYS]> CREATE TABLE tbl1 (
    col1 INT,
    col2 INT
    )
    PARTITION BY RANGE (col1)
    SUBPARTITION BY HASH (col2)
    SUBPARTITIONS 3
    (
        PARTITION p0 VALUES LESS THAN (10),
        PARTITION p1 VALUES LESS THAN (20)
    );
    Query OK, 0 rows affected (0.093 sec)

   ```
 2. 在 `tbl1` 表中插入两条数据。

   ```shell
   obclient [SYS]>  INSERT INTO tbl1 (col1, col2) VALUES (2, 3);
                    INSERT INTO tbl1 (col1, col2) VALUES (15, 2);

   ```
 3. 查询表 `tbl1` 的 `p0`、`p1` 分区中是否插入数据。

   ```shell
   obclient [SYS]> SELECT * FROM tbl1 PARTITION (p0);

   ```

   查询结果如下：

   ```shell
   +------+------+
   | col1 | col2 |
   +------+------+
   |    2 |    3 |
   +------+------+

   ```

   ```shell
   obclient [SYS]> SELECT * FROM tbl1 PARTITION (p1);

   ```

   查询结果如下：

   ```shell
    +------+------+
    | col1 | col2 |
    +------+------+
    |   15 |    2 |
    +------+------+

   ```
 4. 创建分区的表 `tbl2`。

   ```shell
   obclient [SYS]> CREATE TABLE tbl2 (
    col1 INT,
    col2 INT
    )
    PARTITION BY RANGE (col1)
    SUBPARTITION BY HASH (col2)
    SUBPARTITIONS 3
    (
        PARTITION p0 VALUES LESS THAN (10),
        PARTITION p1 VALUES LESS THAN (20)
    );

   ```
 5. 插入两条数据到表 `tbl2` 中。

   ```shell
   obclient [SYS]> INSERT INTO tbl2 (col1, col2) VALUES (0, 22);
                   INSERT INTO tbl2 (col1, col2) VALUES (18, 6);

   ```
 6. 查询表 `tbl2` 中分区 `p0` 和 `p1` 是否有数据插入。

   ```shell
   obclient [SYS]> SELECT * FROM tbl2 PARTITION (p0);

   ```

   查询结果如下：

   ```shell
    +------+------+
    | COL1 | COL2 |
    +------+------+
    |    0 |   22 |
    +------+------+

   ```

   ```shell
   obclient [SYS]> SELECT * FROM tbl2 PARTITION (p1);

   ```

   查询结果如下：

   ```shell
    +------+------+
    | COL1 | COL2 |
    +------+------+
    |   18 |   6 |
    +------+------+

   ```
 7. 使用 `insert overwrite` 将表 `tbl1` 中 p1 分区的数据覆盖写到表 `tbl2` 中。

   ```shell
   obclient [SYS]> INSERT INTO tbl2 PARTITION (p1) SELECT * FROM tbl1 PARTITION (p1);

   ```
 8. 验证表 `tbl2` 中 p1 分区的数据是否已经被覆盖。

   ```

   查询结果如下：

   ```

   结果显示表 `tbl2` 中分区 `p1` 的数据已被替换。

## 使用 MERGE INO 语句插入数据

在批处理任务中，可能需要对目标表进行大量的 `INSERT` 操作。当待插入的数据在表记录中不存在时，也可以使用 `MERGE INTO` 语句将源表的记录插入到目标表中，具体操作及示例请参见 [替换数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682557)。

#### 说明

在使用 `INSERT` 语句插入数据时，如果表上有唯一性约束，则在插入相同的记录时，系统会报错，您可以通过 `MERGE INTO` 语句来更新表记录，避免唯一性约束的冲突。

## 通过 DBLink 使用 INSERT 语句插入数据

当前 OceanBase 数据库支持通过 DBLink 向 OceanBase 数据库（Oracle 模式）和 Oracle 数据库中写入数据。

通过 DBLink 向远端数据库的表 `t1` 中插入一行数据 `(11,11)` 的示例如下：

```shell
obclient> SELECT * FROM t1@ob_dblink;
+------+------+
| C1   | C2   |
+------+------+
|    1 |    1 |
+------+------+
1 row in set

obclient> INSERT INTO t1@ob_dblink VALUES (11,11);
Query OK, 1 row affected

obclient> commit;
Query OK, 0 rows affected

obclient> SELECT * FROM t1@ob_dblink;
+------+------+
| C1   | C2   |
+------+------+
|    1 |    1 |
|   11 |   11 |
+------+------+
2 rows in set

```

OceanBase 数据库 Oracle 模式支持把本地表数据写入（`INSERT`、`DELETE`、`UPDATE` 和 `MERGE INTO`）远端表，详细信息，参见 [通过 DBLink 修改远端数据库中的数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005683100)。

## 相关文档

- [更新数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682558)
 - [删除数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682560)
 - [替换数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005682557)
 - [通过 DBLink 修改远端数据库中的数据](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000005683100)

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
