1
大きなデータベースで一意のインデックス違反が発生しました。元の問題は、格納されたpl/pgsql関数で発生します。更新中のユニークなインデックス違反
問題を示すためにすべてを単純化しました。私はむしろ単純なテーブルでそれを再現することができます:UPDATEは、テーブル内のデータが次のようになります前に
CREATE UNIQUE INDEX test_idx_pos
ON public.test
USING btree
(pos);
:
testdb=# SELECT * FROM test;
id | pos | text
----+-----+----------
2 | 1 | testpos1
3 | 2 | testpos2
1 | 5 | testpos4
4 | 4 | testpos3
(4 Zeilen)
tr: (4 rows)
CREATE TABLE public.test
(
id integer NOT NULL DEFAULT nextval('test_id_seq'::regclass),
pos integer,
text text,
CONSTRAINT text_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.test
OWNER TO root;
GRANT ALL ON TABLE public.test TO root;
は、私が「POS」に一意索引を定義します
今、私は2より大きいすべての 'pos'の値を1減らしたいと思っています(trはドイツ語から英語への私の翻訳です):
UPDATEが完全に実行していた場合はtestdb=# UPDATE test SET pos = pos - 1 WHERE pos > 2;
FEHLER: doppelter Schlüsselwert verletzt Unique-Constraint »test_idx_pos«
tr: ERROR: duplicate key violates unique constraint »test_idx_pos«
DETAIL: Schlüssel »(pos)=(4)« existiert bereits.
tr: key »(pos)=(4) already exists.
テーブルは次のようになりますし、再びユニークである:
testdb=# SELECT * FROM test;
id | pos | text
----+-----+----------
2 | 1 | testpos1
3 | 2 | testpos2
1 | 4 | testpos4
4 | 3 | testpos3
(4 Zeilen)
tr: (4 rows)
にはどうすればこのような事態を回避することができますか?私は、格納されたpl/pgsql関数がトランザクションに組み込まれていることを知ったので、この問題は表示されませんか?
この正確な答えや解決のためにありがとうございました。私の「評判」が小さすぎるので、私はあなたの答えをアップアップすることができません申し訳ありません。私はあなたの答えを今受け入れることさえできません。それは唯一のものなのだろうか? – WKarl
ああ、今できます。時間制限。どのように奇妙な。 なぜ私の質問は-1になったのですか?私は質問する前に答えを探しました、それは不明ではありません - 他にどのようにa_horse_with_no_nameが1分で答えることができ、それは少なくとも私にとっては非常に便利です。 – WKarl