2016-06-13 112 views
0

我有一个触发器执行存储过程的背后,以捕获某些数据更改和插入,用于审计目的。 有一个存储过程将行添加到表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和所有。据我的同事和我可以告诉查询没有任何问题,我们已经使用分析器跟踪和所有的部分正在执行,因为他们应该。当手动运行代码以从tmp_Inserted和tmp_Deleted表中选择时,所以我们可以看到我们正在处理的值是什么,这仍然没有问题。更复杂的是,当INSERT INTO语句自己运行时,新插入的行就像我们所期望的那样出现。

+2

您正在创建tmp_inserted和tmp_deleted表并且不在触发器中使用它们。它是否打算行为?这可能无法解决您的问题,但您可以尝试删除这两个表或在内联INSERT语句中使用它们。 – Swapnil

+0

@Swapnil临时表仅仅是为了帮助我们调试这个问题,当我们能够触发工作时他们会去。现在,它们允许我们查看插入和删除的值,并且如果需要将它们交换到查询中以检查将放入AUDIT_TRAIL表中的内容。 –

+0

我在这里没有看到任何内在错误。但是,如果没有任何表格,我真的很难理解正在发生的事情。 –

回答

1

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

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