2012-07-17 112 views
1

我有一個表Absence與PK AbscenceId(是的拼寫錯誤)。我有另一個表Note,與FK Absence調用AbsenceId(這次拼寫正確)。該FK約束是:刪除觸發器不被執行

ALTER TABLE [dbo].[Note] WITH CHECK ADD CONSTRAINT [FK_Note_Absence] FOREIGN KEY([AbsenceId]) 
REFERENCES [dbo].[Absence] ([AbscenceId]) 
GO 

Absence被刪除,我希望所有Notes去用它。我無法通過CASCADES這樣做,因爲Note也可以屬於其他內容。

所以我創建了一個觸發刪除筆記時不存在被刪除:

ALTER TRIGGER [dbo].[TR_OnAbsenceDelete] ON [dbo].[Absence] 
    FOR DELETE AS 

    DELETE FROM [Note] 
     WHERE AbsenceId IN (SELECT AbscenceId FROM Deleted) 

但是,當我刪除連有一個NoteAbsence,我得到:

Msg 547, Level 16, State 0, Line 1 
The DELETE statement conflicted with the REFERENCE constraint "FK_Note_Absence". The conflict occurred in database "ReturnToWork", table "dbo.Note", column 'AbsenceId'. 
The statement has been terminated.� 

這幾乎就像觸發器沒有被執行一樣?

+0

您是否嘗試過使用INSTEAD-OF觸發器?您還必須刪除最初被刪除的記錄。如果您的FK已經有刪除操作,您將無法使用它。 – 2012-07-17 20:18:29

+0

錯誤信息很明顯,不是嗎?您不能只從'Note'中刪除該行,您還必須清除引用它的其他表中的任何行。 – 2012-07-17 20:20:41

+0

我完全明白了錯誤,我想我只是假定觸發器之前沒有執行過,並且不確定觸發器是否被調用。 – sheamus 2012-07-18 01:07:23

回答

3

你的觸發需要被寫入作爲INSTEAD OF觸發器,首先從注,然後刪除自缺位。

CREATE TRIGGER [dbo].[TR_OnAbsenceDelete] ON [dbo].[Absence] 
    INSTEAD OF DELETE AS 
BEGIN 

    DELETE FROM n 
     FROM deleted d 
      INNER JOIN Note n 
       ON d.AbscenceId = n.AbsenceId 

    DELETE FROM a 
     FROM deleted d 
      INNER JOIN Absence a 
       ON d.AbscenceId = a.AbscenceId 
END 
+0

如果有任何失敗,我會得到一個完整的回滾呢? – sheamus 2012-07-18 01:05:05

+0

我寫了一個ruby腳本來根據FK限制自動做到這一點。很好的工作,也許其他人可以發現它也很有用。我發佈了它[這裏](http://educatedsquirrel.com/2012/07/18/automatically-create-a-cascading-delete-via-triggers/)。 – sheamus 2012-07-18 17:30:09