我有以下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 = 'myemail@mycompany.com',
@body = @b,
@subject = 'Attempt to Delete an order'
RETURN
END
GO
当我尝试从ORDERS表中删除订单时,这是有效的。但是,我无法理解为什么,这个触发器会定期用空体发送电子邮件。据我所知,没有明显的删除订单的尝试。还有什么可能导致这样的空白电子邮件?
答案 0 :(得分:9)
此触发器处理多行删除,如果有人触发不删除任何行的删除语句,也不会向您发送无意义的电子邮件:
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 = 'myemail@mycompany.com',
@body = @b,
@subject = 'Attempt to Delete an order';
RAISERROR('Cannot delete order(s)', 16, 1);
END
RETURN;
END
GO
答案 1 :(得分:2)
关于触发器的最常见错误是它们通常是为每个已删除的记录工作一次而创建的。
但是如果使用一个DELETE语句删除了多个记录,则触发器应该能够像Aaron建议的那样处理所有已删除的记录。
在触发器中避免单值变量非常重要,开发人员应在触发器中构建基于集合的解决方案