我有一个触发器,它在存储过程的后面执行,以捕获某些数据更改和插入,以便进行审计。 有一个存储过程可以向表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语句单独运行时,新插入的行会出现在我们预期的位置。
答案 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..