2011-02-15 82 views

回答

6

一種更容易的替代方法是插入新行,並刪除舊的。 (在刪除之前更新其他表中的任何引用行)

4

如果這就是你以後沒有內置的UPDATE CASCADE。你需要做一些事情,像禁用任何FK約束;運行UPDATE語句;重新啓用約束。

請注意,更新主鍵是(通常總是)一個壞主意。

2

您需要在更改主鍵值之前禁用外鍵約束,然後再重新啓用它們。

如果你真正想實現「級聯更新」的功能,而不是再看看Tom Kyte's Update Cascade package

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) 
+0

儘管此鏈接可能會回答問題,但最好在此處包含答案的重要部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 – 2014-10-27 10:16:05

0

是的,是有辦法做到在Oracle中級聯更新,甚至交易(不啓用/禁用限制的選項保持爲真)之內。但是,你必須自己實現它。它可以通過之前/之後行更新觸發器完成。

由於在檢查任何約束之前執行觸發器,這是可能的。 (至少在Oracle 11.2中是這樣的,沒有檢查過12.1,但我確信它沒有改變。)

無論如何,如前所述,更新主鍵通常是一個壞主意。

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'

0

另一種方法是通過更改外鍵約束,以便在您提交之前延遲約束的驗證 - 即不是通過語句驗證約束語句,而是執行事務處理,通過事務。

請注意,您無法通過「alter table」語句執行此操作,但可以刪除並重新創建外鍵約束以使其可延遲,即i。E:

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約束 - 你會得到一個錯誤,你將不得不修複數據並提交或回滾。

請注意,此功能非常安全,因爲Oracle不允許髒讀,所以一旦提交,它們只會看到更新的效果。所以從其他會話的角度來看,參照完整性似乎得以保留。

此外,這是一次性更改,因此每次您想要更新主鍵時都不需要執行DDL。