更改Oracle中的主键值

时间:2011-02-15 17:23:51

标签: database oracle foreign-keys primary-key

有没有办法将另一个表引用的主键的值更改为外键?

7 个答案:

答案 0 :(得分:6)

更简单的替代方法是插入新行并删除旧行。 (在执行删除之前更新其他表中的任何引用行)

答案 1 :(得分:4)

没有内置的UPDATE CASCADE,如果这就是你所追求的。您需要执行禁用任何FK约束的操作;运行UPDATE语句;重新启用约束。

请注意,更新主键(通常总是)是一个坏主意。

答案 2 :(得分:2)

您需要在更改主键值之前禁用外键约束,然后再重新启用它们。

如果您确实想要实现“更新级联”功能,请参阅Tom Kyte's Update Cascade package

答案 3 :(得分:1)

即使没有禁用约束也是可能的,如果您只想交换密钥(这也是更改的子集,因此它仍然可以回答您的问题)。我在这里写了一个例子:https://stackoverflow.com/a/26584576/1900739

update MY_TABLE t1
set t1.MY_KEY = (case t1.MY_KEY = 100 then 101 else 100 end)
where t1.MYKEY in (100, 101)

答案 4 :(得分:0)

是的,有一种方法可以在Oracle中进行级联更新,即使在事务中也是如此(对于启用/禁用约束的选项不适用)。但是,您必须自己实施。它可以通过之前/之后的行更新触发器来完成。

由于在检查任何约束之前执行触发器是可能的。 (好吧,至少在Oracle 11.2中这是真的.Haven对12.1进行了检查,但老实说我相信它没有改变。)

无论如何,如前所述,更新主键通常是一个坏主意。

答案 5 :(得分:0)

原则是禁用约束,根据键运行你的udates,然后重新启用约束。这是一个运行禁用脚本的脚本: (假设所有约束都在启动时启用)

生成脚本 SELECT 'alter table ' || uc.table_name|| ' disable constraint '|| uc.constraint_name|| ' ;' FROM user_constraints uc inner join user_cons_columns ucc on uc.constraint_name = ucc.constraint_name where column_name = 'MYCOLUMN_USED_AS_FOREIGN_KEY' and constraint_type='R' 复制/粘贴生成的脚本并运行它

alter table MYTABLE1 disable constraint FK_MYTABLE1 ; alter table MYTABLE2 disable constraint MYTABLE2 ; alter table MYTABLE3 disable constraint FK3_MYTABLE3 ; ...

然后更新您的PK值: update MYTABLE1 set MYFIELD= 'foo' where MYFIELD='bar'; update MYTABLE2 set MYFIELD= 'foo' where MYFIELD='bar'; update MYTABLE3 set MYFIELD= 'foo' where MYFIELD='bar'; commit; 生成启用约束脚本:

SELECT 'alter table ' || uc.table_name|| ' enable constraint '|| uc.constraint_name|| ' ;' FROM user_constraints uc inner join user_cons_columns ucc on uc.constraint_name = ucc.constraint_name where column_name = 'MYCOLUMN_USED_AS_FOREIGN_KEY' and constraint_type='R'

答案 6 :(得分:0)

另一种方法是通过更改外键约束,以便约束的验证推迟到您提交 - 即代替Oracle验证约束语句,它将执行事务处理-transaction。

请注意,您无法通过“alter table”语句执行此操作,但您可以删除并重新创建可以延迟的外键约束,即:

alter table <table name> drop constraint <FK constraint name>;
alter table <table name> add constraint <FK constraint name> foreign key .... initially deferrable;

完成后,只需按照您喜欢的顺序更新表,然后提交 - 此时,可以:

  1. 满足你所有的FK限制,每个人都很开心;或
  2. 您在某处违反了FK约束 - 您将收到错误,您必须修复数据并提交或回滚。
  3. 请注意,此功能非常安全,因为Oracle不允许脏读,因此一旦提交,它们只会看到更新的效果。因此,从每个其他会话的角度来看,似乎都保留了引用完整性。

    此外,这是一次性更改,因此每次要更新主键时都不需要执行DDL。