2017-02-12 56 views
3

google搜索了很多後,我的問題是下面描述PostgreSQL的部分指標和UPSERT

[42P10] ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification 

本書雖然這個作品(每個規格):

insert into security (vendor, external_id, extinct) 
    values('Legion', 'LGNONE', false) 
    ON CONFLICT DO NOTHING; 

PostgreSQL documentation stands that it should work

的PostgreSQL V9.5

我的目標是要找到辦法在UPSERT

上多爲空的列此表中創建唯一索引並更新用新的舊行

回答

6

conflict_target使用在on conflict必須標識一個現有的唯一索引。您不能使用

on conflict (vendor, external_id, extinct) 

因爲您在三列中沒有索引。 Postgres並不是很聰明,它可以結合多個索引來滿足你的衝突目標。

但是,您可以創建一個部分索引像這樣的:

create unique index unique_vendor_external_id 
    on security(vendor, external_id, extinct) 
    where coalesce(vendor, external_id) is not null; 

現在你可以使用三列作爲衝突的目標:

insert into security (vendor, external_id, extinct) 
    values('Legion', 'LGNONE', false) 
on conflict (vendor, external_id, extinct)   -- exact match to the index definition 
    where coalesce(vendor, external_id) is not null -- obligatory index_predicate 
do update set 
    vendor = excluded.vendor, 
    external_id = excluded.external_id, 
    extinct = excluded.extinct 

注意使用特殊的記錄excluded的。對於文檔:

SET和WHERE關於衝突的條款DO UPDATE訪問使用表的名稱(或別名)現有行,並使用特殊排除表提出了插入行。

+0

這是絢麗的建議和答案!非常感謝你! – cingulata