他の列が真である場合にのみ、列に一意性を強制する必要があります。コンディション固有の制約が正しく更新されない
create temporary table test(id serial primary key, property character varying(50), value boolean);
insert into test(property, value) values ('a', false);
insert into test(property, value) values ('a', true);
insert into test(property, value) values ('a', false);
そして、私は条件付きインデックスと一意性を強制:たとえば、私がtrueに設定された値を持つ行を変更しようとすると、
create unique index on test(property) where value = true;
をこれまでのところは良い、という問題が生じます。
update test set value = new_value from (select id, id=3 as new_value from test where property = 'a')new_test where test.id = new_test.id
しかし、私はやるときにはしていません:それは私がしなければ動作します
update test set value = new_value from (select id, id=1 as new_value from test where property = 'a')new_test where test.id = new_test.id
そして私が手:
ERROR: duplicate key value violates unique constraint "test_property_idx"
DETAIL: Key (property)=(a) already exists.
********** Error **********
ERROR: duplicate key value violates unique constraint "test_property_idx"
SQL state: 23505
Detail: Key (property)=(a) already exists.
真の値を持つ行がある場合は基本的に、それは動作します真理である現在の行よりも大きな値を持つ主キー。どのようにそれを回避するための任意のアイデア?
私が行うことができます。もちろん、:
update test set value = false where property='a';
update test set value = true where property = 'a' and id = 1;
はしかし、私は、ノードからこれらのクエリを実行していることだし、それが唯一のクエリを実行することが好ましいです。
私は9.5
一意制約DEFERRABLE INITIALLY DEFERREDを作成してください。不幸にも構文がわからない。 –
UNIQUE INDEXではCONSTRAINT UNIQUEでしか使用できません。 –
ストアドファンクションを使用してデータを更新してください。 'update test set value = falseここでproperty = 'a'とvalue;'はより効率的です。 BTW 'update test set value = id = 3ここでproperty = 'a';はより簡単です。 – Abelisto