版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/ctypyb2002/article/details/86238159
os: ubuntu 16.04
db: postgresql 9.6.8
postgresql upsert 是从 9.5 开始引入的功能,语法中并没有 upsert 这个关键字,是通过 insert into 来实现的。
所以现在 postgresql 也可以使用 insert into 来实现 oracle 的 merge into 功能。
强大,赞一个。
语法
# su - postgres
$ psql
psql (9.6.8)
Type "help" for help.
postgres=#
postgres=# \h insert
Command: INSERT
Description: create new rows in a table
Syntax:
[ WITH [ RECURSIVE ] with_query [, ...] ]
INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
[ ON CONFLICT [ conflict_target ] conflict_action ]
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
where conflict_target can be one of:
( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ]
ON CONSTRAINT constraint_name
and conflict_action is one of:
DO NOTHING
DO UPDATE SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) |
( column_name [, ...] ) = ( sub-SELECT )
} [, ...]
[ WHERE condition ]
postgres=#
举例
# su - postgres
$ psql
psql (9.6.8)
Type "help" for help.
postgres=# create table tmp_t0(
c0 varchar(100),
c1 varchar(100),
constraint pk_tmp_t0 primary key (c0)
);
postgres=#
postgres=# insert into tmp_t0
select id::varchar,id::varchar
from generate_series(1,10) as id;
postgres=#
postgres=# select * from tmp_t0;
c0 | c1
----+----
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 8
9 | 9
10 | 10
(10 rows)
不存在则插入,存在则更新
postgres=# insert into tmp_t0 as t0 (c0,c1)
( select *
from ( VALUES ('1'::varchar,'a'::text), ('11'::varchar,'b'::varchar)) t1(c0, c1)
)
on conflict (c0)
do update set c0=excluded.c0,c1=excluded.c1
;
postgres=# select * from tmp_t0;
c0 | c1
----+----
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 8
9 | 9
10 | 10
1 | a
11 | b
(11 rows)
不存在则插入,存在则直接返回,不做任何处理
postgres=# insert into tmp_t0 as t0 (c0,c1)
( select *
from ( VALUES ('2'::varchar,'aa'::text), ('12'::varchar,'bb'::varchar)) t1(c0, c1)
)
on conflict (c0)
do nothing
;
postgres=# select * from tmp_t0;
c0 | c1
----+----
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 | 7
8 | 8
9 | 9
10 | 10
1 | a
11 | b
12 | bb
(12 rows)
参考:
https://helpcdn.aliyun.com/document_detail/52951.html
http://postgres.cn/docs/9.6/sql-insert.html