2016-11-28 36 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行”,因为最终插入是“驱动”此信息的那一个。

相关问题