从审核表中查找更改

时间:2018-06-21 08:27:16

标签: sql-server tsql audit

我在下面的审核表中有数据。 Fiddle 1Fiddle 2

Audit Table

我需要从此表中获取更新的列和数据详细信息。

预期结果是:

  

员工姓名:从Jone到Jhone

     

员工年龄:25至20

     

员工姓名:从Jhonny到Jone,员工年龄:18至25

我该如何实现?

更新

当一条记录被更新时,我要在审计表中插入两行。第一个记录为Old(auditDataState),其中包含更新之前的数据,第二个记录为New(auditDataState),其中包含更新的数据。

因此,每个更新在审核表中都有两个记录,分别为 Old New ,其中包含新旧值。

我需要根据审核表中的updateColumns从审核表中获取更新的数据。(我正在updateColumns列中存储要更新的列)。

我不需要第一行为Employee Name : from Jone to Jhone。只需标识更新的值即可。

1 个答案:

答案 0 :(得分:1)

这将提供问题中指定的结果,尽管它离明智或可扩展的解决方案还很远。如果有可能,我建议您完全重新进行变更审核:

declare @EmpAudit table (
      empID int
    , empName varchar(50)
    , empAge int
    , auditDataState varchar(50)
    , auditDMLAction varchar(50)
    , auditUser varchar(50)
    , auditDateTime datetime
    , updateColumns varchar(50)
);

insert into @EmpAudit values
      (1, 'Alex', 22, 'New', 'Insert','c@a.com',getdate(),''),
      (2, 'Jhonny', 18, 'New', 'Insert','c@a.com',getdate()-0.5,''),

      (2, 'Jhonny', 18, 'Old', 'Update','b@a.com',getdate()-1,'Employee Name, Employee Age'),
      (2, 'Jone', 25, 'New', 'Update','b@a.com',getdate()-1.5,'Employee Name, Employee Age'),

      (2, 'Jone', 25, 'Old', 'Update','a@a.com',getdate()-2,'Employee Age'),
      (2, 'Jone', 30, 'New', 'Update','a@a.com',getdate()-2.5,'Employee Age'),

      (2, 'Jone', 30, 'Old', 'Update','a@a.com',getdate()-3,'Employee Age'),
      (2, 'Jone', 20, 'New', 'Update','a@a.com',getdate()-3.5,'Employee Age'),

      (2, 'Jone', 20, 'Old', 'Update','a@a.com',getdate()-4,'Employee Name'),
      (2, 'Jhone', 20, 'New', 'Update','a@a.com',getdate()-4.5,'Employee Name');

with d as
(
    select empID
            ,empName
            ,empAge
            ,auditDataState
            ,auditDMLAction
            ,auditUser
            ,auditDateTime
            ,updateColumns
            ,row_number() over (partition by empID order by auditDateTime) as rn
    from @EmpAudit
)
select case when o.empName <> n.empName then 'Employee Name : from ' + o.empName + ' to ' + n.empName else '' end
      +case when charindex(',',o.UpdateColumns) > 0 then ', ' else '' end
      +case when o.empAge <> n.empAge then 'Employee Age : from ' + cast(o.empAge as varchar(3)) + ' to ' + cast(n.empAge as varchar(3)) else '' end as Change
from d as o
    join d as n
        on o.empID = n.empID
            and o.updateColumns = n.updateColumns
            and o.rn = n.rn+1
            and n.auditDataState = 'New'
where o.auditDataState = 'Old';

输出:

Change
-----------------------------------------------------------------
Employee Name : from Jone to Jhone
Employee Age : from 30 to 20
Employee Age : from 25 to 30
Employee Name : from Jhonny to Jone, Employee Age : from 18 to 25