2016-11-28 37 views
0

我試圖插入一些行到我的表具有相同的唯一標識符,但所有其他字段是不同的(行代表地圖上的點,他們只是碰巧具有相同的名稱)。我想最終的結果是以某種方式修改違規的行,使其具有唯一的標識符(在標識符上添加一些遞增的數字,例如「name0」,「name1」,「name2」等)插入命令。有沒有一種優雅的方式來處理插入重複標識符的行?

我知道Postgres最近增加了「ON CONFLICT」支持,但它不是我想要的。

按照Postgres 9.6 Documentation

可選的ON CONFLICT子句指定要提高一個獨特的違規或排除約束衝突錯誤的替代作用。對於建議插入的每個單獨的行,插入都會進行,或者...執行替代衝突操作。 ... ON CONFLICT DO UPDATE更新與提議插入的行衝突的現有行,因爲其替代動作

我想要做的是1)要麼修改違規行或插入本身 2)與插入進行(而不是用更新替換它,就像開衝突的功能一樣)。有沒有一個完美的方式來完成這個?或者我需要寫更復雜的東西?

回答

0

你可以這樣做:

create table my_table 
( 
    name text primary key, 
    some_column varchar 
); 

create sequence my_table_seq; 

序列用於分配一個唯一的後綴到新行的PK列。

「插入衝突插入修飾」的行爲可以這樣做:

with data (name, some_column) as (
    values ('foo', 'bar') 
), inserted as (
    insert into my_table 
    select * 
    from data 
    on conflict (name) do nothing 
    returning * 
) 
insert into my_table (name, some_column) 
select concat(name, '_', nextval('my_table_seq')), some_column 
from data 
where not exists (select 1 from inserted); 

第一次插入值的PK列,插入(在CTE「插入」)剛剛進行。最後的insert將不會插入任何內容,因爲where not exists()可以阻止該行爲,因爲inserted返回了一行。

第二次運行此操作時,第一次插入不會插入任何內容,因此第二次(最終)插入將會。

但有一個缺點:如果「插入」CTE插入了某些內容,則總體語句將報告「受影響的0行」,因爲最終插入是「驅動」此信息的那一個。

相關問題