2012-01-04 60 views
1

每隔一段時間我都必須從我們的數據庫中刪除用戶。用戶存儲在名爲TPM_USER的表中。問題是,有一堆表在TPM_USER.USERID上有外鍵約束。更糟糕的是,這些限制使用ON CASCADE DELETE。有一天,我刪除了一個我認爲沒有被任何東西使用的用戶(這是幾個小時前錯誤創建的重複用戶),但它沒有任何警告地清除了一堆重要數據。我可以暫時禁用Oracle中的級聯刪除嗎?

就我個人而言,我討厭級聯刪除。我認爲它們很危險,只有在兩個實體確實相互依賴的情況下才能使用。我很想將它們全部移除,但是這種架構相當複雜,而且這個時候可能會變得太大而無法改變。

我的問題:上運行TPM_USER一個DELETE聲明之前,我可以讓Oracle告訴我到底是什麼會因此而被刪除?或者,如果任何外鍵被違反,我是否可以暫時禁用任何級聯並獲得錯誤?

謝謝!

+0

我個人認爲,*你*的系統中的危險實體。不是'ON CASCADE DELETE'子句;-)我建議編寫一個用於刪除用戶的存儲過程,用於檢查用戶「可能」不應該被刪除的相關情況。 – 2012-01-04 21:19:17

+0

或者如果錯誤,可能會進行處理。如果您需要刪除用戶,指定一些標誌(例如禁用,鎖定,...),並在更長的時間週期(也許是幾周)後刪除。當然,這也會要求應用程序瞭解這種更改,但是更好的做法是使用刪除和從備份恢復;) – rkosegi 2012-01-04 21:23:42

+0

@LukasEder - 哦,我肯定會同意我是危險的組件,特別是玩弄一個我不明白的複雜架構,然後在我破壞事情時公開抱怨。我的問題是我如何保護自己免受級聯刪除造成的繼承危險。 – 2012-01-04 21:34:22

回答

2

在回答你的問題時,我不知道任何簡單的方法來顯示級聯刪除語句中將被刪除的內容。你可以編寫腳本,但它會非常複雜,因爲你必須動態地依賴關係樹,只顯示與刪除標準相關的記錄。

無論如何,你可以通過使用禁用的約束:

alter table TABLE_NAME disable constraint FK_CONSTRAINT_NAME; 

(使用 '啓用' 重新啓用它)。

顯然你應該知道如果你這樣做,而另一個用戶從同一個表中刪除,那麼Oracle將不會執行這個約束,並且可能發生不好的事情。

你可以得到所有的表/約束名稱引用TPM_USER.USERID與列表:

select table_name, constraint_name from user_constraints 
    where r_constraint_name in (
    select constraint_name 
    from user_constraints 
    where constraint_type = 'P' 
    and table_name = 'TPM_USER'); 

(使用ALL_CONSTRAINTS如果您有跨架構的依賴)

+0

'select'語句的'+ 1'獲得引用表的列表,這將*非常有用!如果沒有更具體的內容出現,我會接受這個答案。 – 2012-01-04 22:25:07