代码之家  ›  专栏  ›  技术社区  ›  Chris Farmer Marcelo Cantos

当存在子记录时,是否可以在Oracle中修改记录的主键值?

  •  2
  • Chris Farmer Marcelo Cantos  · 技术社区  · 15 年前

    我有一些Oracle表表示父子关系。它们看起来像这样:

    create table Parent (
        parent_id varchar2(20) not null primary key
    );
    
    create table Child (
        child_id number not null primary key,
        parent_id varchar2(20) not null,
    
        constraint fk_parent_id
            foreign key (parent_id)
            references Parent (parent_id)
    );
    

    这是一个实时数据库,它的模式是在很久以前的假设下设计的 parent_id 对于给定的记录,字段将是静态的且不变的。现在规则已经改变了,我们真的想改变 亲本 为了一些记录。

    例如,我有以下记录:

    Parent:
    
    parent_id
    ---------
    ABC123
    
    
    Child:
    
    child_id  parent_id
    --------  ---------
    1         ABC123
    2         ABC123
    

    我想修改一下 ABC123 在这两个表中都记录了一些其他的东西。

    据我所知,不能编写同时更新父表和子表的Oracle更新语句,并且给定fk约束,我不确定如何最好地更新数据库。我当前正在禁用 fk_parent_id 约束,分别更新每个表,然后启用约束。

    是否有更好的单步更新此内容的方法?

    3 回复  |  直到 15 年前
        1
  •  6
  •   Cade Roux    15 年前

    没有级联更新。

    你可以使用 deferrable constraint .

    或者,在交易中:

    • 使用新键将父级复制到新行:

      插入父级(键、列…) 选择newkey,cols… 来自父母 其中key=oldkey

    • 分配所有子项:

      更新儿童 设置parent_id=newkey 其中parent_id=oldkey

    • 删除父级,现在没有人引用它:

      删除 来自父母 其中key=oldkey

    this link .

        2
  •  3
  •   Vincent Malgrat    15 年前

    如果您发现需要经常更新主键,您可能需要重新考虑您的模型并使用一个真正不变的主键。使用一个具有无意义的代理键的列(递增的标识列或GUID),并将只想更新的值存储在父表中(这样,当需要更新它时,只有一行可以修改)。

        3
  •  2
  •   Tony Andrews    15 年前

    Tom Kyte提供了一个实用程序来实现“更新级联”功能。 here .