Insert Statement不适用于Insert触发器

时间:2016-06-13 12:25:42

标签: sql-server triggers

我有一个触发器,它在存储过程的后面执行,以捕获某些数据更改和插入,以便进行审计。 有一个存储过程可以向表DTA添加行,触发器被编码为从中激发;

CREATE TRIGGER [AUDIT_TRACE]
    ON [DTA]
    AFTER UPDATE, INSERT
AS BEGIN
    SET NOCOUNT ON;

    BEGIN TRANSACTION

        IF EXISTS (SELECT * FROM sys.tables WHERE name = 'tmp_inserted')
            DROP TABLE tmp_inserted 
        IF EXISTS (SELECT * FROM sys.tables WHERE name = 'tmp_deleted')
            DROP TABLE tmp_deleted 
        SELECT * INTO tmp_inserted from inserted
        SELECT * INTO tmp_deleted from deleted

        INSERT INTO [AUDIT_TRAIL]
        SELECT 
            UpdatedDate
            ,UserName
            ,Name
            ,oldValue
            ,newValue
            ,DATATABLEID
            ,ISNULL(AuthInvNo,'')+ISNULL(invNO,'') as InvoiceNumber
            ,AuthAccount As Product
            ,AuthValue AS Value
            ,QTY
            ,InputScreen
        FROM 
        (
            SELECT 
                i.UpdatedDate as [UpdatedDate]
                ,psn.UserName as [Username]
                ,CONCAT(psn.Firstname,' ',psn.surname) as [Name]
                ,CONVERT(nvarchar(36),i.DataTableId) as [DataTableID]
                ,dtType.Description as [InputScreen]
                ,dtat.Description as [ColumnName]
                ,CONVERT(nvarchar(1000),dtText.Text) as [Entry]
                ,dtavB.Description as OldValue
                ,dtavA.Description as NewValue
            FROM dt
            INNER JOIN inserted i on i.DataTableId = dt.DataTableId
            LEFT JOIN deleted d on d.DataTableId = i.DataTableId
            INNER JOIN dtavA on dtavA.DataTableAttributeValueId = i.DataTableAttributeValueId
                                and dtavA.DataTableAttributeTypeId IN ('23087D97-B96B-4015-9E66-258EE7CAF499','2D5E9D64-A2B6-444D-938A-7D8DD66208E0')-- after
            LEFT JOIN dtavB on dtavB.DataTableAttributeValueId = d.DataTableAttributeValueId
                                and dtavB.DataTableAttributeTypeId IN ('23087D97-B96B-4015-9E66-258EE7CAF499','2D5E9D64-A2B6-444D-938A-7D8DD66208E0')-- before
            INNER JOIN dtText on dtText.DataTableId = i.DataTableId
            INNER JOIN dtType on dtType.DataTableTypeId = dt.DataTableTypeID
            INNER JOIN psn on psn.PersonId = i.UpdatedBy
            INNER JOIN dtat on dtat.DataTableAttributeTypeId = dtText.DataTableAttributeTypeId
        )E
        PIVOT(MAX([ENTRY]) FOR [COLUMNNAME] IN(DEBITCREDIT,AuthValue,QTY,AuthAccount,AuthInvNo,InvNO))as p
    COMMIT TRANSACTION
END

现在的问题是,当将数据插入DTA表时,我们的AUDIT_TRAIL表中没有插入任何内容,但是当在DTA表中更新行时,结果正是我们所期望的,oldValue,NewValue和all。至于我的同事和我可以告诉我们查询没有任何问题,我们使用了探查器跟踪,所有部分都按照应有的方式执行。当手动运行代码以从tmp_Inserted和tmp_Deleted表中进行选择时,我们可以看到我们正在处理的值是什么,再次没有问题。更复杂的是,当INSERT INTO语句单独运行时,新插入的行会出现在我们预期的位置。

1 个答案:

答案 0 :(得分:1)

为了确保数据不会被触发器中的insert语句中的JOIN过滤,请通过将其与内联INSERT中的所有表连接来插入INSERTED中的数据。

SELECT I.* INTO tmp_inserted
FROM dt
INNER JOIN inserted i on i.DataTableId = dt.DataTableId
LEFT JOIN deleted d etc..