2012-01-18 43 views
0

我需要在一對SQL表上構建以下邏輯。以下是基本的表結構:帶有條件更新的SQL觸發器

TABLE [dbo].[Email](
    [IssueId] [int] NOT NULL, 
    [NoErrors] [int] NOT NULL, 
    [EmailBody] [nvarchar](max) NULL, 
    ... 
) 

TABLE [dbo].[Inclusion](
    [InclusionId] [int] IDENTITY(1,1) NOT NULL, 
    [IssueId] [int] NOT NULL, 
    ... 
) 

這兩個表的主要關係是IssueId字段上的[Issue]表。每個問題記錄只有一個關聯的電子郵件表,但對於多個包含記錄爲零。

我希望發生的就是這個...

如果夾雜記錄被刪除,這是與此問題相關的最後一個入選的記錄,那麼我想在Email.NoErrors設置爲-1。如果存在其他包含(刪除後),我想按照原樣離開Email.NoErrors。

我寫了下面的扳機,似乎工作:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete] 
    ON [dbo].[Inclusion] 
    AFTER DELETE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    UPDATE Email 
    SET NoErrors = CASE 
     WHEN EXISTS (
      SELECT * FROM Inclusion 
      WHERE IssueId = DELETED.IssueId 
     ) 
     THEN NoErrors -- Leave existing value 
     ELSE 
     (-1) 
     END 
    FROM DELETED 
    WHERE Email.IssueId = DELETED.IssueId 
END 

有兩件事情,我知道足夠的理由擔心。首先,觸發器似乎效率低下,因爲它總是更新Email.NoErrors字段,即使它不必。其次,我知道DELETED參考表可能包含多條記錄,但我不確定我的腳本是否能正確處理 - 但我懷疑不是。

任何意見/方向將不勝感激。

UPDATE
這裏是我結束了最終代碼:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete] 
    ON [dbo].[Inclusion] AFTER DELETE 
AS 

IF @@ROWCOUNT = 1 
BEGIN 
    UPDATE Issue 
    SET NoEmailErrors = -1 
    FROM DELETED 
    WHERE (
     Issue.IssueId = DELETED.IssueId 
     AND Issue.NoEmailErrors != -1 
     AND NOT EXISTS (
     SELECT * 
     FROM Inclusion 
     WHERE Inclusion.IssueId = DELETED.IssueId 
    ) 
    ) 
END 
ELSE 
BEGIN 
    UPDATE Issue 
    SET NoEmailErrors = -1 
    FROM DELETED 
    WHERE (
     Issue.IssueId IN (
     SELECT IssueId FROM DELETED 
    ) 
     AND Issue.NoEmailErrors != -1 
     AND NOT EXISTS (
     SELECT * 
     FROM Inclusion 
     WHERE Inclusion.IssueId = DELETED.IssueId 
    ) 
    ) 
END 

回答

1

這種重寫可以幫助你與效率低下的擔憂:

ALTER TRIGGER [dbo].[trg_Inclusion_Delete] 
    ON [dbo].[Inclusion] 
    AFTER DELETE 
AS 
BEGIN 
SET NOCOUNT ON; 

    UPDATE Email 
    SET NoErrors = -1 
    FROM DELETED 
    WHERE Email.IssueId = DELETED.IssueId 
     AND NOT EXISTS 
     (
      SELECT 'x' FROM Inclusion 
      WHERE Inclusion.IssueId = DELETED.IssueId 
     ) 
END 
+0

謝謝埃裏克,你的代碼是更乾淨。我還發現了以下鏈接http://msdn.microsoft.com/en-us/library/ms190752.aspx,我認爲這與我正在嘗試做的事情有關。我已更新我的原始文章以包含新腳本 – Neilski 2012-01-19 07:42:58