2016-12-06 299 views
3

我想更新表中幾行的主鍵。如果所有行均已更新,則密鑰將再次爲唯一,但第一行的更新會導致與第二行的密鑰的臨時衝突。有沒有一種優雅的方式來解決這個問題?PostgreSQL:更新主鍵,避免衝突

實施例:

create table erichtest (i integer, v varchar(200)); 
alter table erichtest add constraint pk_erichtest primary key(i); 
insert into erichtest values(1, 'Eins'); 
insert into erichtest values(2, 'Zwei'); 
update erichtest set i=i+1; 

ERROR: duplicate key value violates unique constraint "pk_erichtest"

+1

'DEFERRED'是這裏的術語。 – joop

+1

也許轉儲並導入表。但爲什麼更新主鍵?它不應直接與記錄相關。 – kometen

+0

@kometen:就我而言,這是一張小桌子,用戶可以重新排列此表格中項目的顯示順序。如果用戶將第三個項目移動到第一個位置,實際的update語句如下所示:'update foobar set i = case when i = 3 then 1 else i + 1 end where I in 1 and 3'。也許'i'不是主鍵的好選擇,但在Oracle中,這種方式的效果與預期的一樣......並且由於我們使用Slony-I來進行復制,因此我們需要一個主鍵。 –

回答

4

Something like this should help

b=# begin; 
BEGIN 
b=# alter table erichtest drop constraint pk_erichtest ; 
ALTER TABLE 
b=# alter table erichtest add constraint pk_erichtest primary key (i) DEFERRABLE INITIALLY IMMEDIATE; 
ALTER TABLE 
b=# set constraints pk_erichtest deferred ; 
SET CONSTRAINTS 
b=# update erichtest set i=i+1; 
UPDATE 2 
b=# select * from erichtest ; 
i | v 
---+------ 
2 | Eins 
3 | Zwei 
(2 rows) 

b=# end; 
COMMIT 
2

添加10減法9:

update erichtest set i=i+10; 
update erichtest set i=i-9;