2013-07-15 46 views
0

這裏有一個數據庫模型的簡化版本,我目前正與合作:數據庫模型的問題,「在刪除設置爲空」

Simple DB model of stores and customers (crow's foot DB notation)

域的快速解釋:

  • 每家商店可以有多個客戶。每個客戶實體引用單個應用程序用戶帳戶(即用戶和商店之間的多對多關係)。
  • 每個商店都可以設置折扣類別(商店也可以沒有設置)。
  • 客戶可以添加到折扣類別中,以在商店購物時獲得折扣。

我目前在客戶和商店之間的FK上有一個'ON DELETE CASCADE'。也就是說,當商店被刪除時,商店的顧客將被刪除。我在折扣類別和商店之間的FK上也有一個'ON DELETE CASCADE'。也就是說,當商店被刪除時,商店的折扣類別被刪除。

現在考慮商店所有者想要移除折扣類別的情況。我想在客戶和折扣類別之間的FK上設置'ON DELETE SET NULL'。

如果我嘗試在SqlServer中這樣做,它會抱怨通常的'多級聯路徑'問題。

問題:是否有任何優雅的方式來重新構建此問題,以便在刪除折扣類別時將客戶從折扣類別中刪除(即將FK設置爲​​空),同時仍保持其他級聯關係?假設我不能離開SqlServer。

+1

菱形級聯可以相當簡單地通過觸發器進行仿真。有沒有一個特定的原因可以避免這種情況? –

+0

感謝您的評論Branko。我看了一下觸發器。如果我理解正確,AFTER觸發器將不起作用,因爲在刪除發生之前需要關閉FK。 INSTEAD OF觸發器也不起作用,因爲我在Store和Discount Category之間定義了級聯刪除。 – sammy34

+0

P.S.諾維薩德的可愛:)。我比貝爾格萊德更喜歡它! – sammy34

回答

1

您可以通過INSTEAD OF DELETE觸發器實現ON CASCADE DELETE,即使存在多個級聯路徑時也可以使用。

這裏是一個「模板」:

CREATE TRIGGER PARENT_TRIGGER ON PARENT_TABLE INSTEAD OF DELETE AS 
BEGIN 

    SET NOCOUNT ON; 

    DELETE FROM CHILD_TABLE 
    WHERE EXISTS (
     SELECT * FROM deleted 
     WHERE CHILD_TABLE.PK = deleted.PK 
    ); 

    -- You can DELETE from other child table here, etc... 

END 
GO 

請注意,您將無法混合聲明級聯和觸發 - 你需要執行觸發器一路下跌。

+0

Hvala Branko。考慮到我最初的問題,我認爲你的答案是正確的,但是我最終以不同的方式解決了問題,因爲我不想在整個級聯分支上實現觸發器。當從應用程序級別中刪除折扣類別(全部在原子性的一個事務中)時,我的解決方案涉及批量更新所有客戶(關閉他們的FK)。對於我的情況,這是一個比完整的觸發器更好的方法。 Ziveli :)。 – sammy34