postgresql9.5新特性upsert

这个特性的意思是insert数据时,如果不冲突,就insert成功,如果冲突,就执行update操作。

先看简单代码:

postgres=# create table t(id1 int primary key, id2 int, d1 text,d2 text);
CREATE TABLE
postgres=# insert into t values(1,1,'1','1');
INSERT 0 1
如果insert数据主键冲突,则执行update。
postgres=# insert into t values(1,2,'2','2') on conflict(id1) do update set d1=excluded.d1,d2=excluded.d2;
INSERT 0 1
postgres=# select * from t;
 id1 | id2 | d1 | d2 
-----+-----+----+----
   1 |   1 | 2  | 2
(1 row)
如果insert数据主键冲突,不执行任何操作。
postgres=# insert into t values(1,2,'3','3') on conflict(id1) do nothing;
INSERT 0 0
postgres=# select * from t;
 id1 | id2 | d1 | d2 
-----+-----+----+----
   1 |   1 | 2  | 2
(1 row)

再来看非主键情况。

postgres=# truncate table t;
TRUNCATE TABLE
postgres=# insert into t values(1,1,'1','1');
INSERT 0 1
postgres=# insert into t values(1,1,'2','2') on conflict(id2) do update set d1=excluded.d1,d2=excluded.d2;
ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
STATEMENT:  insert into t values(1,1,'2','2') on conflict(id2) do update set d1=excluded.d1,d2=excluded.d2;
ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
没有排他约束,保存。添加唯一索引后执行。
postgres=# create unique index idx_t_id2 on t(id2);
CREATE INDEX
postgres=# insert into t values(1,1,'2','2') on conflict(id2) do update set d1=excluded.d1,d2=excluded.d2;
INSERT 0 1
postgres=# select * from t;
 id1 | id2 | d1 | d2 
-----+-----+----+----
   1 |   1 | 2  | 2
(1 row)

唯一索引为null的情况

postgres=# truncate table t;
TRUNCATE TABLE
postgres=# insert into t values(1,null,'1','1');
INSERT 0 1
postgres=# insert into t values(2,null,'2','2') on conflict(id2) do update set d1=excluded.d1,d2=excluded.d2;
INSERT 0 1
postgres=# select * from t;
 id1 | id2 | d1 | d2 
-----+-----+----+----
   1 |     | 1  | 1
   2 |     | 2  | 2
(2 rows)

update常量的情况

postgres=# truncate table t;
TRUNCATE TABLE
postgres=# insert into t values(1,1,'1','1');
INSERT 0 1
postgres=# insert into t values(1,1,'2','2') on conflict(id1) do update set d1='a',d2='b';
INSERT 0 1
postgres=# select * from t;
 id1 | id2 | d1 | d2 
-----+-----+----+----
   1 |   1 | a  | b
(1 row)

后记

要了解更详细的信息,还是看官网文档:http://www.postgresql.org/docs/9.5/static/sql-insert.html    ,我这里只写了一部分简单的情况。

如果一个表有30个字段,只有第一个字段是主键,那么insert冲突的时候,是否应该写29个update赋值语句呢?这个感觉还有待改进。

你可能感兴趣的:(postgresql9.5新特性upsert)