2008-10-22 126 views

回答

22

直接從the manual ...

我們知道外鍵不允許不涉及到任何產品的訂單的創建。但是,如果在創建引用它的訂單後刪除產品? SQL允許你處理這個。直觀地說,我們有幾種選擇:

不允許刪除一個被引用的產品

刪除訂單,以及

別的東西嗎?

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

限制和級聯刪除是兩種最常用的選項。 RESTRICT防止刪除引用的行。 NO ACTION表示如果在檢查約束時仍然存在任何引用行,則會引發錯誤;如果不指定任何內容,這是默認行爲。 (這兩個選擇之間的主要區別在於,NO ACTION允許將檢查推遲到事務的後期,而RESTRICT則不)。CASCADE指定刪除引用行時,引用它的行應自動刪除以及。還有兩個選項:SET NULL和SET DEFAULT。這些導致引用列分別被設置爲空值或默認值,當被引用的行被刪除時。請注意,這些不會讓您無法觀察任何約束條件。例如,如果某個操作指定了SET DEFAULT,但默認值不滿足該外鍵,則該操作將失敗。

與ON DELETE類似,還有ON UPDATE,它在被引用的列被更改(更新)時被調用。可能的行動是相同的。

編輯:你可能想看看此相關的問題:When/Why to use Cascading in SQL Server?。問題背後的概念是一樣的。

0

我有一個PostGreSQL數據庫,當我有一個用戶從數據庫中刪除並且我需要從其他表中刪除它的信息時,我使用On Delete。這種方式我需要做的只有1刪除和具有ON刪除的FK將從其他表中刪除信息。

您可以使用ON更新。如果您更新了表格並且該字段具有帶更新的FK,如果在FK上進行了更改,您將在FK表中發現。

0

Daok說的是真的......它可能相當方便。另一方面,讓事情自動發生在數據庫中可能是一個真正的問題,尤其是當涉及到消除數據時。未來有人可能會指望FK通常在有孩子的情況下防止刪除父母,並且沒有意識到您使用On Delete Cascade不僅不能防止刪除,而且會導致大量數據在數十個其他表由於級聯刪除的瀑布而消失。

@ Arthur的評論。

在數據庫中發生的「隱藏」事情越頻繁,任何人都能很好地處理髮生的事情的可能性就越小。觸發器(這實質上是一個觸發器)可以導致我簡單的刪除行,以在整個數據庫中產生廣泛的後果。我發出了刪除語句,17個表受到級聯的觸發器和約束的影響,並且這些對於命令的發佈者來說都不是立即顯而易見的。 OTOH,如果我將刪除父母及其所有孩子放在一個程序中,那麼任何人都很容易清楚地看到我發出命令時會發生什麼。

它完全與我設計數據庫的方式無關。它與觸發器引入的操作問題有關。

+1

如果架構設計正確,我認爲這不是問題。通常孩子(FKs)的數據在沒有父母的情況下並不真正有用。 – 2008-10-22 15:30:40

0

而不是編寫方法來完成級聯刪除或級聯更新的所有工作,您可以直接編寫一條警告消息。比重新創建輪子要容易得多,並且它向客戶端清楚(並且新開發人員拿起代碼)