Триггер обновления SQL Server для массовых обновлений - PullRequest
3 голосов
/ 02 июля 2010

Ниже приведен триггер обновления SQL Server 2005.Для каждого обновления таблицы email_subscriberList, где изменяется флаг isActive, мы вставляем запись аудита в таблицу email_Events.Это прекрасно работает для отдельных обновлений, но для массовых обновлений записывается только последняя обновленная строка.Как преобразовать приведенный ниже код, чтобы выполнить вставку для каждой обновленной строки?

CREATE TRIGGER [dbo].[Email_SubscriberList_UpdateEmailEventsForUpdate_TRG]
ON [dbo].[Email_subscriberList]
FOR UPDATE
AS
DECLARE @CustomerId int
DECLARE @internalId int
DECLARE @oldIsActive bit
DECLARE @newIsActive bit
DECLARE @email_address varchar(255)
DECLARE @mailinglist_name varchar(255)
DECLARE @email_event_type varchar(1)

SELECT @oldIsActive = isActive from Deleted 
SELECT @newIsActive = isActive from Inserted

IF @oldIsActive <> @newIsActive

 BEGIN

 IF @newIsActive = 1
     BEGIN
     SELECT @email_event_type = 'S'
     END
 ELSE
     BEGIN
     SELECT @email_event_type = 'U'
     END


 SELECT @CustomerId = customerid from Inserted
 SELECT @internalId = internalId from Inserted
 SELECT @email_address = (select email from customer where customerid = @CustomerId)
 SELECT @mailinglist_name = (select listDescription from Email_lists where internalId = @internalId)

 INSERT INTO Email_Events
 (mailshot_id, date, email_address, email_event_type, mailinglist_name)
 VALUES
 (@internalId, getDate(), @email_address, @email_event_type,@mailinglist_name)

 END

Ответы [ 2 ]

2 голосов
/ 02 июля 2010

Левые внешние объединения, так как в случае, если нет связанных записей в customer или email_Lists (как это возможно в текущем коде) - сделайте их внутренними объединениями, если вы знаете, что будут присутствовать данные (т.е. внешние ключи на месте) .

CREATE TRIGGER [dbo].[Email_SubscriberList_UpdateEmailEventsForUpdate_TRG] 
ON [dbo].[Email_subscriberList] 
FOR UPDATE 
AS 

INSERT INTO Email_Events
  (mailshot_id, date, email_address, email_event_type, mailinglist_name) 
 select
    i.InternalId
   ,getdate()
   ,cu.Email
   ,case i.IsaActive
      when 1 then 'S'
      else 'U'
    end
   ,el.ListDescription
  from inserted i
   inner join deleted d
    on i.CustomerId = d.CustomerId
     and i.IsActive <> d.IsActive
   left outer join Customer cu
    on cu.CustomerId = i.CustomerId
   left outer join Email_Lists el
    on el.InternalId = i.InternalId

Проверьте это хорошо, особенно для проблем параллелизма. Эти соединения внутри триггера заставляют меня нервничать.

2 голосов
/ 02 июля 2010

пример

непроверенных

CREATE TRIGGER [dbo].[Email_SubscriberList_UpdateEmailEventsForUpdate_TRG]
ON [dbo].[Email_subscriberList]
FOR UPDATE
AS


 INSERT INTO Email_Events
 (mailshot_id, date, email_address, email_event_type, mailinglist_name)
 SELECT i.internalId,getDate(),c.email, 
 case i.isActive when 1 then 'S' else 'U' end,e.listDescription
 from Inserted i
 join deleted d on i.customerid = d.customerid
 and i.isActive  <> d.isActive 
 join customer c on i.customerid = c.customerid
 join Email_lists e on e.internalId = i.internalId
...