数据库和数据表创建完成后,可以使用 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 NULL、PRIMARY KEY、UNIQUE、FOREIGN KEY、CHECK等)等,避免插入数据时报错。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)如果列属性
Nullable为not null,即不允许为NULL时,如果列属性Default有配置默认值,则可以在插入时不指定该列的值,系统会在该列上插入配置好的默认值。否则必须指定该列的值,不然会报错。如果列属性
Nullable为NULL,则可以在插入时不指定该列的值,系统会在该列上插入一个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 没有被更新。