T-SQL INSTEAD OF DELETE Триггер срабатывает без «провокации» - PullRequest
2 голосов
/ 07 февраля 2012

У меня есть следующий триггер 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.Однако я не могу понять почему, этот триггер продолжает периодически отправлять электронные письма с пустым телом.Насколько я знаю, нет очевидных попыток удалить заказ.Что еще может вызвать такие пустые письма?

Ответы [ 2 ]

9 голосов
/ 07 февраля 2012

Этот триггер обрабатывает удаление нескольких строк, а также не беспокоит отправку вам бессмысленного электронного письма, если кто-то запускает оператор удаления, который не удаляет строки:

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 голосов
/ 07 февраля 2012

Самая распространенная ошибка в триггерах заключается в том, что они обычно создаются, поскольку они будут работать один раз для каждой удаленной записи.

Но если более одной записи удаляется одним оператором DELETE, триггер должен иметь возможностьобрабатывать все удаленные записи, как предложил Аарон.

Важно избегать переменных с одним значением в триггере, разработчики должны строить решения на основе множеств в триггерах

...