W przypadku PostgreSQL można to rozwiązać tylko w „ładny” sposób, używając wersji 9.0, ponieważ można tam zdefiniować unikalne ograniczenia, które można odroczyć.
Z PostgreSQL 9.0 po prostu zrobisz:
create table label (
id_label serial not null,
rank integer not null,
title text not null,
constraint pri primary key (id_label)
);
alter table label add constraint unique_rank unique (rank)
deferrable initially immediate;
W takim razie aktualizacja jest tak prosta:
begin;
set constraints unique_rank DEFERRED;
update rank
set rank = case when rank = 20 then 10 else 20 end
where id_label in (1,2);
commit;
Edycja:
Jeśli nie chcesz zawracać sobie głowy ustawianiem ograniczenia na odroczone w ramach transakcji, możesz po prostu zdefiniować ograniczenie jako initially deferred
.