2009-03-23 9 views
1

私はデータベースの状況に遭遇しましたが、私は数日のレコードのタイムスタンプをシフトする必要がありますが、idフィールドとタイムスタンプフィールドを必要とするユニークな制約がありますユニーク。データベースの更新注文

ここに表の説明があります。

Table "public.eedata" 
    Column |    Type    |       Modifiers       
-------------+--------------------------------+------------------------------------------------------------ 
eedata_id | bigint       | not null default nextval('eedata_eedata_id_seq'::regclass) 
user_id  | integer      | 
eeupload_id | bigint       | 
eetimestamp | timestamp(0) without time zone | 
Indexes: 
    "pk_eedata" PRIMARY KEY, btree (eedata_id) 
    "eedata_user_id_key" UNIQUE, btree (user_id, eetimestamp) 
    "fki_eeuploadid" btree (eeupload_id) 
Foreign-key constraints: 
    "fk_eeupload_id" FOREIGN KEY (eeupload_id) REFERENCES eeupload(eeupload_id) ON UPDATE CASCADE ON DELETE CASCADE 
    "fk_user_id" FOREIGN KEY (user_id) REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE CASCADE 

この問題は、eedata_user_id_key制約によって発生します。それは中に更新を適用する順序は、任意の衝突を防ぐため、私は正常に私が

update eedata set eetimestamp = eetimestamp + interval '1 day' where eeupload_id = xxx;

は私がするために必要なもの

ERROR: duplicate key violates unique constraint "eedata_user_id_key"
を取得しようとただしたときに、使用日

update eedata set eetimestamp = eetimestamp - interval '1 day' where eeupload_id = xxx;

を引くことができます更新が適用される順序(事実上、更新ステートメントのためにorder by)、または単一の更新ステートメントの制約を中断する能力を指定することができます。

私はPostgres 8.1.11を使用しています。

答えて

3

更新の間、制約を削除してから、もう一度追加することができますか?

+0

それは彼に重複を残すだろうか? –

+0

それはうまくいくでしょう、そして、それは私が行く必要があるルートかもしれませんが、受け入れる前にそれを扱うよりエレガントな方法があるかどうかを見たいと思っています。 –

+0

しないでください。彼の現在の状態が有効な場合、彼のコマンドは1日追加されます。更新の途中で彼は一時的な無効状態になるので、後までルールの有効性をチェックしないことで問題を回避します。 オラクルでは、コミットするまでアップデートのチェックを延期することができます。 – Elie

0

私は最近同様の問題がありました。私は2008年9月に終了するテストデータを持っています。私は6ヶ月間動かしましたが、重複していました。私がする必要があったのは、作成される前に重複を検出し、新しい行のINSERTの代わりに既存の行を更新することでした。