postgresql upsert 的实现

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据库人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值