postgresql 冲突时不使用自定义约束

2ekbmq32  于 5个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(93)

我需要执行以下操作:

insert into table_a (primarykey_field, other_field)
select primarykey_field, other_field from table_b b
on conflict (primarykey_field) where primarykey_field >>= b.primarykey_field do nothing;

字符串
不管我的where条件的操作,它可以是任何东西,除了一个简单的相等。在我的情况下,我使用一个自定义的ip范围字段,所以我想检查一个ip地址不在其他ip地址的范围内,当我插入一个新的行。
有没有一种方法可以用on conflict或另一个查询来做到这一点?

cnjp1d6j

cnjp1d6j1#

您可以过滤掉所有具有pkey_ip_range的行,这些行已经包含在现有的pkey_ip_range中:

insert into table_a as a (
    pkey_ip_range, 
    other_field)
select  pkey_ip_range, 
        other_field 
from table_b b
where not exists (
    select 1 
    from table_a 
    where b.pkey_ip_range >>= table_a.pkey_ip_range);

字符串
如果你想检查传入的ip范围是否包含现有的ip范围(&& rather than >>=),你可以使用排除约束:

drop table if exists table_a;
create table table_a (
    pkey_ip_range inet primary key, 
    other_column text);
alter table table_a
add constraint table_a_no_contained_ip_ranges
exclude using gist (pkey_ip_range inet_ops WITH &&);

insert into table_a 
(pkey_ip_range,other_column) 
values ('192.168.0.0/31','abc');

insert into table_a 
(pkey_ip_range,other_column) 
values ('192.168.0.0/30','def');
ERROR:  conflicting key value violates exclusion constraint "table_a_no_contained_ip_ranges"
DETAIL:  Key (pkey_ip_range)=(192.168.0.0/30) conflicts with existing key (pkey_ip_range)=(192.168.0.0/31).
insert into table_a 
(pkey_ip_range,other_column) 
values ('192.168.0.0/32','ghi') 
on conflict do nothing;
table table_a;

| pkey_ip_range|其他栏|
| --|--|
| 192.168.0.0/31 | ABC|

相关问题