2012-01-18 12 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, 
    ... 
) 

両方のテーブルの主な関係は、[Issue]フィールドの[Issue]テーブルです。各Issueレコードには、関連付けられた電子メールテーブルが1つしかありませんが、0〜多数のInclusionレコードがあります。私は起こるしたい何

はこれです...

封入レコードが削除され、それが問題に関連付けられている最後のインクルージョンレコードだったされている場合、私は-1にEmail.NoErrorsを設定します。他のインクルージョンが存在する場合(削除後)、私は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 

を私が心配するのに十分知っている2つのものがあります。まず、トリガは非効率であるように見えますが、Email.NoErrorsは必ずしも更新される必要はありません。第二に、DELETED参照テーブルに複数のレコードが含まれている可能性がありますが、私のスクリプトがこれを正しく処理できるかどうかはわかりませんが、私はそうは思わないと思います。

アドバイス/指示があれば幸いです。

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

このリライト非効率性の問題であなたを助けるかもしれない:ここで

UPDATE
は私が終わった最終的なコードがある

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