T-SQL INSTEAD OF DELETE 触发器在没有“挑衅”的情况下触发
Posted
技术标签:
【中文标题】T-SQL INSTEAD OF DELETE 触发器在没有“挑衅”的情况下触发【英文标题】:T-SQL INSTEAD OF DELETE Trigger fires without 'provocation' 【发布时间】:2012-02-06 21:32:56 【问题描述】:我有以下 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 表中删除订单时,此方法有效。但是,我不明白为什么,这个触发器会定期发送带有空正文的电子邮件。据我所知,没有明显的尝试删除订单。还有什么可能导致这样的空白电子邮件?
【问题讨论】:
此触发器不适用于行集,你知道吗?另外,orders
有带有删除级联选项的外键吗?
也许它会在某人执行delete orders where 1=0
时触发,而@OrderID
最终会变成null
。我想那也会使 @b
为空。
只有一种方法可以找到:SQL Profiler。
您可以设置扩展事件跟踪以在触发器触发时捕获 TSQL 调用堆栈Example code here
【参考方案1】:
此触发器处理多行删除,并且如果有人触发不删除任何行的删除语句,也不会向您发送无意义的电子邮件:
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
【讨论】:
【参考方案2】:关于触发器的最常见错误是它们通常被创建,因为它们将为每个删除的记录工作一次。
但是如果使用一条 DELETE 语句删除了超过 1 条记录,则触发器应该能够按照 Aaron 的建议处理所有已删除的记录。
避免在触发器中使用单值变量很重要,开发人员应在触发器中构建基于集合的解决方案
【讨论】:
以上是关于T-SQL INSTEAD OF DELETE 触发器在没有“挑衅”的情况下触发的主要内容,如果未能解决你的问题,请参考以下文章
Performance - Inefficient use of keySet iterator instead of entrySet iterator
xlwings: Write Excel macro using python instead of VBA
PostCSS received undefined instead of CSS string
[ES2015] Number.isNaN instead of isNaN