PostgreSQL - 正确更改表行的ID

时间:2013-03-07 09:10:39

标签: postgresql postgresql-9.2

如何更改某些表格行的ID?

像:

UPDATE table SET id=10 WHERE id=5;

但顺便说一下,它会将更改级联到每个引用此表的其他表中吗?

我想这样做,因为我需要从另一个拥有大多数相同表的数据库中导入数据,但是ID不同。因此,如果id与旧数据库匹配,则更容易正确导入数据。

2 个答案:

答案 0 :(得分:9)

假设您有这两个表:

create table referenced (id integer primary key);
create table referencer (a integer references referenced (id));

引用的表引用引用表:

=> \d referencer
  Table "public.referencer"
 Column |  Type   | Modifiers 
--------+---------+-----------
 a      | integer | 
Foreign-key constraints:
    "referencer_a_fkey" FOREIGN KEY (a) REFERENCES referenced(id)

然后在两者中插入一个值:

insert into referenced values (1);
insert into referencer values (1);

select *
from
    referenced rd
    inner join
    referencer rr on rd.id = rr.a
;
 id | a 
----+---
  1 | 1

现在您要将引用更改为on update cascade

alter table referencer
    drop constraint referencer_a_fkey,
    add foreign key (a) references referenced (id) on update cascade;

并更新它:

update referenced set id = 2;

select *
from
    referenced rd
    inner join
    referencer rr on rd.id = rr.a
;
 id | a 
----+---
  2 | 2

如果已更新的ID已存在,那么在引用的表主键中您将遇到另一个问题。但这会产生另一个问题。

更新

这很危险,所以首先备份数据库。它必须以超级用户身份完成:

update pg_constraint
set confupdtype = 'c'
where conname in (
    select
        c.conname
    from
        pg_constraint c
        inner join
        pg_class referenced on referenced.oid = c.confrelid
    where
        referenced.relname = 'referenced'
        and
        c.contype = 'f'
);

它会将引用表上的所有外键约束更改为on update cascade

答案 1 :(得分:2)

您需要更改外键并将ON UPDATE操作设置为CASCADE。更改值时,所有关联的值也将更改。

这是一个如何定义它的例子:

CREATE TABLE order_items (
    product_no integer REFERENCES products ON UPDATE CASCADE,
    order_id integer REFERENCES orders ON UPDATE CASCADE,
    quantity integer,
    PRIMARY KEY (product_no, order_id)
);

有关详细信息,请参阅http://www.postgresql.org/docs/current/static/ddl-constraints.html