插入数据

最近更新时间: 2026-03-13 09:03:00

数据库和数据表创建完成后,可以使用 INSERT INTO ... 语句向表中插入行记录。
INSERT 用于向一张表中插入数据,期望插入的数据可以是一条,多条或者是一个select查询的结果集。
语法如下:

INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ]
    { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }

参数说明:

  • table_name: 一个已有表的名称(可以被模式限定)。

  • alias: table_name 的替补名称。当提供了一个别名时,它会完全隐藏掉表的实际名称。

  • column_name: table_name 表中的列名。如果需要,可以使用子字段名或数组下标限定列名。(如果只向复合列的某些字段插入数据,则其他字段将为空)。

  • DEFAULT VALUES: 所有列都将被其默认值填充。

  • expression: 要赋予给相应列的表达式或者值。

  • DEFAULT: 相应的列将被其默认值填充。

  • query: 提供要被插入行的查询(SELECT语句)。 其语法描述请参考SELECT语句。
    插入数据前要注意:

  • 插入数据前,建议通过 \d table_name 语句查看表结构及列信息,包括数据类型、取值范围、列约束(如NOT NULLPRIMARY KEYUNIQUEFOREIGN KEYCHECK 等)等,避免插入数据时报错。

    tdsql=#\d tbase_insert;
               Table "public.tbase_insert"
    Column   |  Type   | Collation | Nullable |  Default 
    -----------+---------+-----------+----------+------------
    id        | numeric |           | not null |
    name      | text    |           | not null |
    value     | numeric |           |          |
    create_ts | date    |           | not null | CURRENT_DATE
    Indexes:
    "tbase_insert_pkey" PRIMARY KEY, btree (id)
    "uniq_idx_value" UNIQUE, btree (value)
    
  • 如果列属性 Nullablenot null,即不允许为 NULL 时,如果列属性Default有配置默认值,则可以在插入时不指定该列的值,系统会在该列上插入配置好的默认值。否则必须指定该列的值,不然会报错。

  • 如果列属性 NullableNULL,则可以在插入时不指定该列的值,系统会在该列上插入一个 NULL 值。

示例

通过 INSERT 语句可以插入单条数据。可以执行多个单条插入语句来插入多条数据。
表结构如下:

CREATE TABLE tbase_insert(
    id numeric NOT NULL PRIMARY KEY,
    name text NOT NULL, 
    value numeric,
    create_ts DATE NOT NULL DEFAULT CURRENT_DATE 
 );

其中,表的 id 列、name 列不能为空,且 id 列为主键,满足唯一性约束要求,不能有重复的值; create_ts 列指定了获取当前时间作为默认值。
1、使用多个单条插入语句插入多行数据。
由于 create_ts 列指定了默认值,在插入数据时可以不指定该列。

tdsql=# set nls_date_format to 'YYYY-MM-DD';
SET
tdsql=# INSERT INTO tbase_insert(id, name, value) VALUES (1,'tbase',100);
INSERT 0 1
tdsql=# INSERT INTO tbase_insert(id, name, value) VALUES (2,'tbase',101);
INSERT 0 1

注意:

如果create_ts列未指定默认值,则在插入数据时,必须指定值。

insert into tbase_insert values(3 ,'tbase', 102, '1999-1-1');   

2、如果要批量插入多条记录,也可以用一个 INSERT 语句包含多个 VALUES 的内容来批量插入。批量插入语句比多个单条插入语句要快。

tdsql=# insert into tbase_insert values(4,'TDSQL PG', 103),(5,'TDSQL PG好', 104);
INSERT 0 2
tdsql=# select * from tbase_insert;
id |    name    | value | create_ts  
----+------------+-------+------------
  1 | tbase      |   100 | 2024-03-02
  2 | tbase      |   101 | 2024-03-02
  3 | tbase      |   102 | 1999-01-01
  4 | TDSQL PG   |   103 | 2024-03-02
  5 | TDSQL PG好 |   104 | 2024-03-02
(5 rows)

此外,当需要备份表数据或者将一个表的全部记录复制到另一个表时,可以使用查询语句 INSERT INTO ... SELECT ... FROM 进行批量插入。
3、将表 tbase_insert 中的全部数据备份到 tbase_insert_bak 表中。

tdsql=# select * from tbase_insert;
id |    name    | value | create_ts  
----+------------+-------+------------
  1 | tbase      |   100 | 2024-03-02
  2 | tbase      |   101 | 2024-03-02
  3 | tbase      |   102 | 1999-01-01
  4 | TDSQL PG   |   103 | 2024-03-02
  5 | TDSQL PG好 |   104 | 2024-03-02
(5 rows)

tdsql=# CREATE TABLE tbase_insert_bak(
            id numeric NOT NULL PRIMARY KEY,
            name text NOT NULL,
            value numeric,
            create_ts DATE NOT NULL DEFAULT CURRENT_DATE
);
CREATE TABLE

tdsql=# INSERT INTO tbase_insert_bak SELECT * FROM tbase_insert;
INSERT 0 5

tdsql=# select * from tbase_insert_bak;
id |    name    | value | create_ts  
----+------------+-------+------------
  1 | tbase      |   100 | 2024-03-02
  2 | tbase      |   101 | 2024-03-02
  3 | tbase      |   102 | 1999-01-01
  4 | TDSQL PG   |   103 | 2024-03-02
  5 | TDSQL PG好 |   104 | 2024-03-02
(5 rows)

4、返回插入的数据。

tdsql=# create table ins(i int, j int);
CREATE TABLE
tdsql=# insert into ins values (1,1) returning *;
 i | j 
---+---
 1 | 1
(1 row)

INSERT 0 1

5、 使用insert all一次性往多个表插入数据(oracle库下特有语法)

---将数据(1,1)插入ins1和ins2两张表
db_ora=# create table ins1(i int, j int);
CREATE TABLE
db_ora=# create table ins2(i int, j int);
CREATE TABLE
db_ora=# insert all into ins1 values (f1,f2) into ins2 values(f1,f2) select 1 as f1,1 as f2;
INSERT 0 2
db_ora=# select * from ins1;
I | J 
---+---
 1 | 1
(1 row)

db_ora=# select * from ins2;
I | J 
---+---
 1 | 1
(1 row)

使用INSERT...ON CONFLICT方式进行数据更新

在INSERT插入数据时候,如果存在主键或唯一索引冲突,可以使用ON CONFLICT DO UPDATE方式选择更新冲突部分数据,无冲突部分的数据将会正常插入。
示例,使用ON CONFLICT UPDATE更新数据,示例中插入id为3的value存在冲突,将name值更新为 'TDSQL PG Good', id值为6的value正常插入:

tdsql=# select * from tbase_insert;
id |    name    | value | create_ts  
----+------------+-------+------------
  1 | tbase      |   100 | 2024-03-02
  2 | tbase      |   101 | 2024-03-02
  3 | tbase      |   102 | 1999-01-01
  4 | TDSQL PG   |   103 | 2024-03-02
  5 | TDSQL PG好 |   104 | 2024-03-02
(5 rows)

tdsql=# insert into tbase_insert values (3,'TDSQL PG Good', 102),(6,'tbase', 105) on conflict(id) do update set name=excluded.name;
INSERT 0 2
tdsql=# select * from tbase_insert;
id |     name      | value | create_ts  
----+---------------+-------+------------
  1 | tbase         |   100 | 2024-03-02
  2 | tbase         |   101 | 2024-03-02
  4 | TDSQL PG      |   103 | 2024-03-02
  5 | TDSQL PG好    |   104 | 2024-03-02
  3 | TDSQL PG Good |   102 | 1999-01-01
  6 | tbase         |   105 | 2024-03-02
(6 rows)

可以看到 id 值为 3 的 name 被修改为了 TDSQL PG Good, 增加了 id 为 6 的一条数据。
如果存在冲突也可以使用 ON CONFLICT DO NOTHING 选择冲突的 value 不做处理,也不报错。

tdsql=# select * from tbase_insert;
id |     name      | value | create_ts  
----+---------------+-------+------------
  1 | tbase         |   100 | 2024-03-02
  2 | tbase         |   101 | 2024-03-02
  4 | TDSQL PG      |   103 | 2024-03-02
  5 | TDSQL PG好    |   104 | 2024-03-02
  3 | TDSQL PG Good |   102 | 1999-01-01
  6 | tbase         |   105 | 2024-03-02
(6 rows)
tdsql=# insert into tbase_insert values (3,'TDSQL PG nice', 102) on conflict(id) do nothing;
INSERT 0 0
tdsql=# select * from tbase_insert;
id |     name      | value | create_ts  
----+---------------+-------+------------
  1 | tbase         |   100 | 2024-03-02
  2 | tbase         |   101 | 2024-03-02
  4 | TDSQL PG      |   103 | 2024-03-02
  5 | TDSQL PG好    |   104 | 2024-03-02
  3 | TDSQL PG Good |   102 | 1999-01-01
  6 | tbase         |   105 | 2024-03-02
(6 rows)

可以看到 id 值为 3 的 name 没有被更新。