2012-02-06 106 views
2

我有以下INSTEAD OF DELETE觸發器,它在回滾任何刪除嘗試時發送一封電子郵件。T-SQL INSTEAD OF DELETE觸發器觸發時沒有'挑釁'

ALTER TRIGGER tr_OnDel_Orders 
ON ORDERS 
INSTEAD OF DELETE 
AS 
BEGIN 

SET NOCOUNT ON; 

declare @b varchar(5000) 
Declare @OrderID BIGINT, 

SELECT @OrderID = OrderID 
FROM deleted d 

set @b = 'Someone attempted to delete the following order:' + CHAR(10); 
set @b = @b + ' OrderID: ' + cast(@OrderID as varchar(30)) + CHAR(10); 
set @b = @b + ' UserID: ' + SYSTEM_USER 

RAISERROR('Cannot delete order', 16, 1) 
ROLLBACK TRAN 

EXEC msdb.dbo.sp_send_dbmail @recipients = '[email protected]', 
         @body = @b, 
         @subject = 'Attempt to Delete an order' 


RETURN 
END 
GO 

這適用於我嘗試從ORDERS表中刪除訂單。但是,我不明白爲什麼,這個觸發器會定期發送空的郵件。據我所知,沒有明顯的嘗試刪除訂單。還有什麼可能導致這樣的空白電子郵件?

+3

這觸發不排工作組內的一套基於解決方案的單一值的變量是很重要的,你知道嗎?另外,有'訂單'刪除級聯選項的外鍵? – danihp 2012-02-06 21:36:03

+3

也許它會在有人'刪除1 = 0時的訂單','@ OrderID'最終爲'null'時觸發。我想,這會使'@ b'無效。 – Blorgbeard 2012-02-06 21:37:47

+1

只有一種方法可以找出:SQL事件探查器。 – 2012-02-06 21:43:57

回答

9

這觸發處理多行刪除,也不會打擾你發送一個無意義的電子郵件,如果有人觸發DELETE語句不刪除任何行:

ALTER TRIGGER dbo.tr_OnDel_Orders 
ON dbo.ORDERS 
INSTEAD OF DELETE 
AS 
BEGIN 
    IF EXISTS (SELECT 1 FROM deleted) 
    BEGIN 
    SET NOCOUNT ON; 

    DECLARE @b VARCHAR(5000) = ''; 

    SELECT @b = @b + ',' + CONVERT(VARCHAR(12), OrderID) 
     FROM deleted; 

    SET @b = 'Someone attempted to delete the following orders:' 
     + CHAR(10) + @b + CHAR(10) + ' UserID: ' + SYSTEM_USER; 

    ROLLBACK TRANSACTION; -- should probably check @@TRANCOUNT first! 

    EXEC msdb.dbo.sp_send_dbmail 
     @recipients = '[email protected]', 
     @body = @b, 
     @subject = 'Attempt to Delete an order'; 

    RAISERROR('Cannot delete order(s)', 16, 1); 
    END 

    RETURN; 
END 
GO 
2

最常見的錯誤關於觸發器是通常創建它們,因爲它們將爲每個刪除的記錄工作一次。

但是,如果使用一條DELETE語句刪除多個記錄,觸發器應該能夠像Aaron所建議的那樣處理所有刪除的記錄。

,以避免觸發,開發者應該建立觸發器