2014-09-25 239 views
0

我是觸發器的新手,我處於必須使用觸發器的位置。我有一個在桌面上有兩個觸發器的天青數據庫,一個在插入,一個在更新。在觸發另一個觸發器後啓用觸發器

插入:當記錄插入表格時觸發。複製一個列到另一個:

CREATE TRIGGER [dbo].[tr_Set_Adjusted_StartDateTime] 
ON [dbo].[Work] 
AFTER INSERT 
AS 
BEGIN 
    UPDATE dbo.Work 
    SET [ActualStartDateTime] = [work].[StartDateTime] 
    FROM inserted 
    WHERE dbo.Work.WorkUID = inserted.WorkUID; 
END 

更新觸發(火災時,該記錄被更新):

CREATE TRIGGER [dbo].[tr_Set_Actual_EndDateTime] 
ON [dbo].[Work] 
AFTER UPDATE 
AS 
    IF((Select [ActualEndDateTime] from Deleted) is null) 
    BEGIN 
     UPDATE dbo.Work 
     SET [ActualEndDateTime] = GETUTCDATE() 
     FROM deleted 
     WHERE dbo.Work.WorkUID = deleted.WorkUID; 
    END 

第二個觸發應該只執行一次:第一次記錄更新。因爲插入記錄的存儲過程不會填充所有列。

第二個觸發器原本沒有IF語句。但有一個管理站點可以操縱數據庫並啓動更新觸發器。

IF語句現在會立即自動觸發更新觸發器。

有沒有辦法禁用更新觸發器,如果​​它被另一個觸發器執行?或者只在記錄創建後啓用更新觸發器?

+0

注意--''''''''''''可以包含*多行*(或無行)。所以'IF'檢查可能會被破壞,因爲您可能處於* some行的測試結果爲真的情況,對於其他行,測試將是錯誤的。 – 2014-09-26 06:44:46

回答

0

如果在表上有一個After Update觸發器,每當該表上有更新時,它都會觸發。你不能告訴觸發器只發射一次。

但是有一種解決方法。您可以在該表中添加一個字段BIT字段,並將其值設置爲1。永遠不要直接操縱該字段。而你的UPDATE觸發器

UPDATE w 
SET [ActualEndDateTime] = GETUTCDATE() 
    ,[Tr_Update] = 1 
FROM deleted d INNER JOIN dbo.Work w ON w.WorkUID = d.WorkUID 
WHERE [Tr_Update] = 0 
AND [ActualEndDateTime] IS NULL 

在一個側面內注意要檢查,如果用戶還沒有把你想當前日期時間添加到[ActualEndDateTime]列的任何日期。而且由於這是一個經過更新的觸發,如果你只是執行與WHERE子句[ActualEndDateTime] IS NULL上面的語句,

這將更新[ActualEndDateTime]到當前日期時間一行時,首次和下一次因爲[ActualEndDateTime]場更新不會是空的,反而會將其過濾出來。

UPDATE w 
SET [ActualEndDateTime] = GETUTCDATE() 
FROM deleted d INNER JOIN dbo.Work w ON w.WorkUID = d.WorkUID 
WHERE [ActualEndDateTime] IS NULL 
+0

對不起,我現在比較困惑。你是否在插入觸發器中將新位字段設置爲1?我不跟隨你的答案如何工作。操作流程如下:插入 - >觸發器1(更新) - >觸發器2(更新)。我需要它:插入 - >觸發器1(更新)。然後稍後當記錄更新(而不是來自插入觸發器)觸發器2.將RECURSIVE_TRIGGERS {OFF}設置在這裏工作嗎? – Ju66ernaut 2014-09-26 04:59:24