2016-06-13 108 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..