用于批量更新的SQL Server Update触发器

时间:2010-07-02 14:50:42

标签: sql sql-server-2005 tsql triggers

下面是SQL Server 2005更新触发器。对于isActive标志更改的email_subscriberList表上的每次更新,我们都会在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 个答案:

答案 0 :(得分:2)

例如

未测试

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

答案 1 :(得分:2)

左外连接,以防万一客户或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

测试得很好,特别是对于并发问题。触发器中的那些连接让我感到紧张。