删除后的SQL触发器在Deleted Pseudotable中具有Null值?

时间:2014-12-09 09:19:22

标签: sql triggers sql-server-2012

我试图在尝试删除记录时尝试使此触发器工作。它的工作方式是,当有人试图删除记录时,它会回滚并将审计记录插入到TbAudit表中,顺便说一句,所有列都有一个NOT NULL约束。然而,事实证明它不会这样做,因为由于某种原因我不明白当我尝试删除记录时它将显示消息和回滚但是我在select语句中的所有变量都获得NULL值,即使我直接从它中拉出它们"删除"表。请帮忙。

USE BdPlan
GO
CREATE TRIGGER TrAudit
   ON  Plan.TPlan
   AFTER DELETE
AS 
BEGIN
DECLARE @IdPlan = int,
        @IdEmployee int,
        @Month int,
        @Year int

ROLLBACK
PRINT 'CANT DELETE RECORDS'

-- All variables are getting NULL

SELECT  @IdPlan = D.IdPlan,            
        @IdEmployee = D.IdEmployee ,   
        @Month = D.Month,              
        @Year = D.Year                 

FROM    deleted AS D

INSERT INTO BdAudit.dbo.TbAudit
           VALUES
               (
               @IdPlan,
               @IdEmployee,
               @Month,
               @Year,
               SUSER_NAME(),
               GETDATE()
               )
END

1 个答案:

答案 0 :(得分:1)

我认为这种方法可能存在问题:

  • 您正在尝试在事务回滚后尝试访问DELETED伪代码 - 回滚后它将为零行(见下文)
  • 您的触发器只会尝试处理单行删除 - 它应该能够处理多行删除

还注意到,在ROLLBACK之前从Deleted pseudotable直接插入Audit表格当然也会回滚审计数据。

From here显然你可以在@Temporary表变量中缓存要审计的数据,然后执行ROLLBACK(它不会撤消@Temp表) ,然后执行审计插入:

ALTER trigger d_foo ON FOO AFTER DELETE
AS BEGIN
    DECLARE @Temp AS TABLE
    (
        ID INT, 
        -- Obviously add all your fields go here
    );

    INSERT INTO @Temp(ID)
        SELECT ID FROM DELETED;

    ROLLBACK TRAN;

    insert into fooaudit(id)
        select id from @Temp;
END;

Simplified SqlFiddle here多行删除。

要确认,DELETED pseudotable在触发器中的ROLLBACK之后包含零行,如此modified Fiddle demonstrates