需要建议以根据审计表重新创建表的历史记录

Posted

技术标签:

【中文标题】需要建议以根据审计表重新创建表的历史记录【英文标题】:Need advice to re-create history of a table based on audit tables 【发布时间】:2012-11-07 04:13:01 【问题描述】:

好的,伙计们,我有一个紧急需求。我的任务是根据每个字段的单独审计表追溯地重新创建活动表的多个字段更改的准确历史记录。我有一个 SQL Server 代理作业,目前每天从 2012 年 10 月 16 日开始执行此操作,但需要立即添加记录以将历史改回 2012 年 1 月 1 日。

为了使我的问题更加复杂,我需要根据这些审计记录从上到下反映对整个层次结构的每日更改。

这是我所拥有的:

活动表:

empId varchar(20),
first_name varchar(50),
last_name varchar(50),
cost_center varchar(20), -- need to re-create history
mgr_empId varchar(20), -- need to re-create history
start_dt date, -- starting date range of active record
end_dt date, -- end of active record - default value of 12/31/2999 = active record
hierarchy_empId varchar (200), --derived field from a nasty self-referencing function (12x)
hierarchy_name varchar(1000) -- derived from the same function as the field above.

例子:

员工 A1000,Tim Lee 于 2012 年 3 月 1 日进入组织,经理 Bill A(员工 ID B1000)进入成本中心 01552。

A1000 蒂姆·李 01552 B1000 3/1/2012 12/31/2999 B1000>A1000 比尔 A>蒂姆·李 B1000 法案 A 01552 NULL 1/1/2011 12/31/2999 B1000 法案 A

在 2012 年 5 月 1 日,夜间作业为 Tim 获取了一个增量,并且 Tim 的成本中心更改为 31550。因此,他的当前记录更新为昨天的结束日期,并输入了一个新的“当前”记录,反映如下:

A1000 蒂姆·李 01552 B1000 3/1/2012 4/30/2012 B1000>A1000 比尔 A>蒂姆·李 B1000 法案 A 01552 NULL 1/1/2011 12/31/2999 B1000 法案 A A1000 蒂姆·李 31550 B1000 5/1/2012 12/31/2999 B1000>A1000 比尔 A>蒂姆·李

2012 年 6 月 15 日,在 Tim 的经理手下聘用了新经理 Ben C,员工 ID C1000:

A1000 蒂姆·李 01552 B1000 3/1/2012 4/30/2012 B1000>A1000 比尔 A>蒂姆·李 B1000 法案 A 01552 NULL 1/1/2011 12/31/2999 B1000 法案 A A1000 蒂姆·李 31550 B1000 5/1/2012 6/14/2012 B1000>A1000 比尔 A>蒂姆·李 C1000 本 C 31550 A1000 6/15/2012 12/31/2999 A1000>C1000 比尔 A>本 C A1000 蒂姆·李 31550 B1000 6/15/2012 12/31/2999 B1000>C1000>A1000 比尔 A>Ben C>蒂姆·李

这些更新必须沿层级递减。所以,如果蒂姆上面有什么变化,也必须反映在他的记录中。

7 月 15 日,Tim 的原经理 Bill A 获得了新经理 Mark S,员工 ID X3000。

A1000 蒂姆·李 01552 B1000 3/1/2012 4/30/2012 B1000>A1000 比尔 A>蒂姆·李 B1000 法案 A 01552 NULL 1/1/2011 7/14/2012 B1000 法案 A A1000 蒂姆·李 31550 B1000 5/1/2012 6/14/2012 B1000>A1000 比尔 A>蒂姆·李 C1000 本 C 31550 A1000 6/15/2012 7/14/2012 A1000>C1000 比尔 A>本 C A1000 蒂姆李 31550 C1000 6/15/2012 7/14/2012 B1000>C1000>A1000 比尔 A>Ben C>蒂姆李 X3000 Mark S 01000 NULL 7/15/2012 12/31/2999 X3000 Mark S A1000 蒂姆·李 31550 C1000 7/15/2012 12/31/2999 X3000>B1000>C1000>A1000 Mark S>Bill A>Ben C>Tim Lee B1000 账单 A 01552 X3000 7/15/2012 12/31/2999 X3000>B1000 马克 S>账单 A C1000 本 C 31550 B1000 7/15/2012 12/31/2999 X3000>B1000>C1000 马克 S>比尔 A>本 C

我有这些审计表:

tblManagerAudit

empId varchar(20),
chgTimestamp datetime,
oldMgr varchar(20),
newMgr varchar(20)

tblCostCenterAudit

empId varchar(20),
chgTimnestamp datetime,
oldCostCenter varchar(20),
newCostCenter varchar(20)

长期以来,我一直在为如何合并审计记录而苦苦挣扎,并感谢任何意见。

【问题讨论】:

你有样本数据吗?看起来您需要使用 WITH 的递归解决方案 【参考方案1】:

我认为这应该让你继续前进:

SELECT ma1.*, ma2.*
FROM ManagerAudit ma1
LEFT JOIN ManagerAudit ma2
ON ma1.empId = ma2.empId
    and ma1.chgTimestamp < ma2.chgTimestamp
AND NOT EXISTS
  (SELECT * FROM ManagerAudit ma3
   WHERE ma3.empID = ma1.empID
         AND ma3.chgTimestamp > ma1.chgTimestamp
         AND ma3.chgTimestamp < ma2.chgTimestamp)

【讨论】:

以上是关于需要建议以根据审计表重新创建表的历史记录的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用渐变维度的情况下在维度中创建数据历史记录?

需要从github上下载所有的审计日志和大量的历史记录。

使用 Django Model 类继承为表创建审计日志

使用 Hibernate Envers 进行审计

设计一种审计表更改的方法

SQL Server 2016 - 临时表 - 如何识别用户