sql >> Base de Datos >  >> RDS >> PostgreSQL

Índice único parcial de PostgreSQL y upsert

No creo que sea posible usar múltiples índices parciales como objetivo de conflicto. Debe intentar lograr el comportamiento deseado utilizando un solo índice. La única forma que puedo ver es usar un índice único en las expresiones:

drop table if exists test;
create table test (
    p text not null,
    q text,
    r text,
    txt text
);

create unique index test_unique_idx on test (p, coalesce(q, ''), coalesce(r, ''));

Ahora las tres pruebas (ejecutadas dos veces) violan el mismo índice:

insert into test(p,q,r,txt) values ('p',null,null,'a'); -- violates test_unique_idx
insert into test(p,q,r,txt) values ('p','q',null,'b');  -- violates test_unique_idx
insert into test(p,q,r,txt) values ('p',null, 'r','c'); -- violates test_unique_idx

En el comando de inserción debe pasar las expresiones utilizadas en la definición del índice:

insert into test as u (p,q,r,txt) 
values ('p',null,'r','d') 
on conflict (p, coalesce(q, ''), coalesce(r, '')) do update 
set txt = excluded.txt;