2017-06-20 60 views
0

我有更新視圖系統的INSERT規則,爲此,我想實現的UPSERT,如:的PostgreSQL 9.5 UPSERT在規則

CREATE OR REPLACE RULE _insert AS 
ON INSERT TO vue_pays_gex.bals 
DO INSTEAD (
INSERT INTO geo_pays_gex.voie(name, code, district) VALUES (new.name, new.code, new.district) 
ON CONFLICT DO NOTHING; 

但我因爲有可能是這些許多不同的組合三列,我不認爲我可以設置一個CONSTRAINT,包括它們全部(儘管我可能錯過了SQL邏輯中的一個理解點),因此取消了ON CONFLIT DO NOTHING部分。

理想的解決方案似乎是使用EXCEPT,但它只能在INSERT INTO SELECT語句中使用。有沒有辦法使用引用新插入的行的INSERT INTO SELECT語句?像從new.bals(在我的情況)?

如果不是我可以想象一個WHERE NOT EXISTS條件,但是會出現與以前相同的問題。

我猜這是一個相當普遍的SQL需求,但無法找到如何解決它。任何想法?

編輯:

按照要求,這裏是表的定義:

CREATE TABLE geo_pays_gex.voie 
(
    id_voie serial NOT NULL, 
    name character varying(50), 
    code character varying(15), 
    district character varying(50), 
    CONSTRAINT prk_constraint_voie PRIMARY KEY (id_voie), 
    CONSTRAINT voie_unique_key UNIQUE (name, code, district) 
); 

回答

1

你是如何定義的獨特性?如果是名稱+代碼+分區的組合,則只需在表geo_pays_gex.voie上添加約束UNIQUE(name, code, district)。 3,一起,必須是unique ...但你可以有幾次相同的名稱,代碼或區域。

看到它http://rextester.com/EWR73154

編輯 ***

既然你可以有空值,並希望將它們視爲一個獨特的價值,你可以通過更換一個唯一索引替代創建約束nulls

CREATE UNIQUE INDEX 
voie_uniq ON voie 
(COALESCE(name,''), code, COALESCE(district,'')); 
+0

我會試試,如果是這樣的話,正如我懷疑的那樣,這是我對SQL的理解缺乏。謝謝 –

+0

它不工作。在檢查衝突時,檢查是否完成了所有約束?包括主鍵一個?因爲如果是這種情況,即使我使用多個UNIQUE約束,它也會添加一個包含完全相同組合但具有另一個ID的新行。我的ID是一個自動增量SERIAL,因此它被生成。 –

+0

我試圖添加我想要檢查的列,但仍然插入一個新行ON CONFLICT(名稱,代碼,區)不做任何... –