这个特性的意思是insert数据时,如果不冲突,就insert成功,如果冲突,就执行update操作。
先看简单代码:
postgres=#createtablet(id1intprimarykey,id2int,d1text,d2text); CREATETABLE postgres=#insertintotvalues(1,1,'1','1'); INSERT01 如果insert数据主键冲突,则执行update。 postgres=#insertintotvalues(1,2,'2','2')onconflict(id1)doupdatesetd1=excluded.d1,d2=excluded.d2; INSERT01 postgres=#select*fromt; id1|id2|d1|d2 -----+-----+----+---- 1|1|2|2 (1row) 如果insert数据主键冲突,不执行任何操作。 postgres=#insertintotvalues(1,'3','3')onconflict(id1)donothing; INSERT00 postgres=#select*fromt; id1|id2|d1|d2 -----+-----+----+---- 1|1|2|2 (1row)
再来看非主键情况。
postgres=#truncatetablet; TRUNCATETABLE postgres=#insertintotvalues(1,'1'); INSERT01 postgres=#insertintotvalues(1,'2')onconflict(id2)doupdatesetd1=excluded.d1,d2=excluded.d2; ERROR:thereisnouniqueorexclusionconstraintmatchingtheONCONFLICTspecification STATEMENT:insertintotvalues(1,d2=excluded.d2; ERROR:thereisnouniqueorexclusionconstraintmatchingtheONCONFLICTspecification 没有排他约束,保存。添加唯一索引后执行。 postgres=#createuniqueindexidx_t_id2ont(id2); CREATEINDEX postgres=#insertintotvalues(1,d2=excluded.d2; INSERT01 postgres=#select*fromt; id1|id2|d1|d2 -----+-----+----+---- 1|1|2|2 (1row)
唯一索引为null的情况
postgres=#truncatetablet; TRUNCATETABLE postgres=#insertintotvalues(1,null,'1'); INSERT01 postgres=#insertintotvalues(2,d2=excluded.d2; INSERT01 postgres=#select*fromt; id1|id2|d1|d2 -----+-----+----+---- 1||1|1 2||2|2 (2rows)
update常量的情况
postgres=#truncatetablet; TRUNCATETABLE postgres=#insertintotvalues(1,'2')onconflict(id1)doupdatesetd1='a',d2='b'; INSERT01 postgres=#select*fromt; id1|id2|d1|d2 -----+-----+----+---- 1|1|a|b (1row)
后记
要了解更详细的信息,还是看官网文档:http://www.postgresql.org/docs/9.5/static/sql-insert.html ,我这里只写了一部分简单的情况。
如果一个表有30个字段,只有第一个字段是主键,那么insert冲突的时候,是否应该写29个update赋值语句呢?这个感觉还有待改进。
原文链接:https://www.f2er.com/postgresql/194813.html