这个特性的意思是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赋值语句呢?这个感觉还有待改进。