我遇到了与Building a snapshot table from audit records相关的问题。下面的代码部分地解决了我的问题
Select * into #temp from (
SELECT Audit.PrimaryKeyValue as ID,Audit.FieldName,OldValue FROM audit left JOIN (
SELECT Audit.FieldName,Audit.PrimaryKeyValue, MAX(UpdateDate) AS dateadded FROM audit GROUP BY FieldName,PrimaryKeyValue
) maxtimestamp ON audit.FieldName = maxtimestamp.FieldName AND audit.updateDate = maxtimestamp.dateadded
where PrimaryKeyField='Id' and cast(UpdateDate as date)<=@Data) src
pivot(
max(src.OldValue)
for FieldName in (Centrala,ID_Grup,Pi, Ci, Pmt, Pneta, Rpp, Pd, UD, Suport1, Suport2, Suport3, Stare,
Motiv, Observatii, Comentarii, Un, Data_ADD, Modified_Date, Scada, Fuel_base)
) piv;
如何在给定时刻根据审计跟踪表中的记录获取表的快照。 通过在临时表中复制实际表并根据审计内容更新它的值是一种解决方案吗? 我的英文程度不高! 感谢!!!
主表的结构是:
[ID] [int] IDENTITY(1,1) NOT NULL,
[Centrala] [int] NOT NULL,
[ID_grup] [nvarchar](50) NULL,
[Pi] [float] NULL,
[Ci] [float] NULL,
[Pmt] [float] NULL,
[Pneta] [float] NULL,
[Rpp] [float] NULL,
[Pd] [float] NULL,
[UD] [nvarchar](50) NULL,
[Suport1] [nvarchar](255) NULL,
[Suport2] [nvarchar](255) NULL,
[Suport3] [nvarchar](255) NULL,
[Stare] [int] NULL,
[Motiv] [nvarchar](max) NULL,
[Observatii] [nvarchar](max) NULL,
[Comentarii] [nvarchar](max) NULL,
[Un] [varchar](10) NULL,
[Data_ADD] [date] NULL,
[Modified_Date] [date] NULL,
[Scada] [nvarchar](100) NULL,
[Fuel_base] [nvarchar](255) NULL,
并且Audit表的结构是:
[AuditID] [int] IDENTITY(1,1) NOT NULL,
[Type] [char](1) NULL,
[TableName] [varchar](128) NULL,
[PrimaryKeyField] [varchar](1000) NULL,
[PrimaryKeyValue] [varchar](1000) NULL,
[FieldName] [varchar](128) NULL,
[OldValue] [varchar](1000) NULL,
[NewValue] [varchar](1000) NULL,
[UpdateDate] [datetime] NULL,
[UserName] [varchar](128) NULL
用户可以修改主表中的值,包括删除整行,审计表捕获所有修改。我必须在特定日期及时回溯主表的内容。我认为Audit表中的列名是富有表现力的,Type有三个值'U','I','D'用于更新,插入和删除操作。另一个问题是,如果Audit表包含主表中行的修改,并且快照的日期低于Audit中的updateDate,那么我必须选择OldValue else NewValue。它是正确的? 谢谢你@ Nick.McDermaid的回复!!
答案 0 :(得分:0)
我发现了一个非常难看的解决方案,但我认为它现在可以正常工作
Declare @data date
select @data='2016.02.2'
select * into #Grup1 from Grupuri
--Apply to actual values most oldest values from Audit
select * into #temp from (
SELECT
Audit.PrimaryKeyValue as ID,Audit.FieldName,OldValue
FROM audit inner JOIN (
SELECT Audit.FieldName,Audit.PrimaryKeyValue, min(UpdateDate) AS dateadded FROM audit GROUP BY FieldName,PrimaryKeyValue
) maxtimestamp ON audit.FieldName = maxtimestamp.FieldName AND audit.updateDate = maxtimestamp.dateadded
where PrimaryKeyField='Id' and TableName='Grupuri' ) src
pivot(
max(src.OldValue)
for FieldName in (Centrala,ID_Grup,Pi, Ci, Pmt, Pneta, Rpp, Pd, UD, Suport1, Suport2, Suport3, Stare,
Motiv, Observatii, Comentarii, Un, Data_ADD, Modified_Date, Scada, Fuel_base)
) piv;
UPDATE #Grup1 SET Pi= (case When b.Pi is not null then b.Pi else #Grup1.Pi end),
Ci=case When b.Ci is not null then b.Ci else #Grup1.Ci end,
Pmt=case When b.Pmt is not null then b.Pmt else #Grup1.Pmt end,
Pneta=case When b.Pneta is not null then b.Pneta else #Grup1.Pneta end,
Rpp=case When b.Rpp is not null then b.Rpp else #Grup1.Rpp end,
Pd=case When b.Pd is not null then b.Pd else #Grup1.Pd end,
UD=case When b.Ud is not null then b.Ud else NULL end,
Suport1=case When b.Suport1 is not null then b.Suport1 else #Grup1.Suport1 end,
Suport2=case When b.Suport2 is not null then b.Suport2 else #Grup1.Suport2 end,
Suport3=case When b.Suport3 is not null then b.Suport3 else #Grup1.Suport3 end,
Stare=case When b.Stare is not null then b.Stare else #Grup1.Stare end,
Motiv=case When b.Motiv is not null then b.Motiv else #Grup1.Motiv end,
Observatii=case When b.Observatii is not null then b.Observatii else #Grup1.Observatii end,
Comentarii=case When b.Comentarii is not null then b.Comentarii else #Grup1.Comentarii end,
Un=case When b.Un is not null then b.Un else #Grup1.Un end,
Scada= case When b.Scada is not null then b.Scada else #Grup1.Scada end,
Fuel_base=case When b.Fuel_base is not null then b.Fuel_base else #Grup1.Fuel_base end
FROM #temp b WHERE #Grup1.id = b.id
--Apply new values updated up to @data
select * into #temp1 from (
SELECT
Audit.PrimaryKeyValue as ID,Audit.FieldName,NewValue
FROM audit left JOIN (
SELECT Audit.FieldName,Audit.PrimaryKeyValue, MAX(UpdateDate) AS dateadded FROM audit GROUP BY FieldName,PrimaryKeyValue
) maxtimestamp ON audit.FieldName = maxtimestamp.FieldName AND audit.updateDate = maxtimestamp.dateadded
where PrimaryKeyField='Id' and TableName='Grupuri'
and cast(UpdateDate as date) <=@Data) src
pivot(
max(src.NewValue)
for FieldName in (Centrala,ID_Grup,Pi, Ci, Pmt, Pneta, Rpp, Pd, UD, Suport1, Suport2, Suport3, Stare,
Motiv, Observatii, Comentarii, Un, Data_ADD, Modified_Date, Scada, Fuel_base)) piv;
UPDATE #Grup1 SET Pi= (case When b.Pi is not null then b.Pi else #Grup1.Pi end),
Ci=case When b.Ci is not null then b.Ci else #Grup1.Ci end,
Pmt=case When b.Pmt is not null then b.Pmt else #Grup1.Pmt end,
Pneta=case When b.Pneta is not null then b.Pneta else #Grup1.Pneta end,
Rpp=case When b.Rpp is not null then b.Rpp else #Grup1.Rpp end,
Pd=case When b.Pd is not null then b.Pd else #Grup1.Pd end,
UD=case When b.Ud is not null then b.Ud else '-' end,
Suport1=case When b.Suport1 is not null then b.Suport1 else #Grup1.Suport1 end,
Suport2=case When b.Suport2 is not null then b.Suport2 else #Grup1.Suport2 end,
Suport3=case When b.Suport3 is not null then b.Suport3 else #Grup1.Suport3 end,
Stare=case When b.Stare is not null then b.Stare else #Grup1.Stare end,
Motiv=case When b.Motiv is not null then b.Motiv else #Grup1.Motiv end,
Observatii=case When b.Observatii is not null then b.Observatii else #Grup1.Observatii end,
Comentarii=case When b.Comentarii is not null then b.Comentarii else #Grup1.Comentarii end,
Un=case When b.Un is not null then b.Un else #Grup1.Un end,
Scada= case When b.Scada is not null then b.Scada else #Grup1.Scada end,
Fuel_base=case When b.Fuel_base is not null then b.Fuel_base else #Grup1.Fuel_base end
FROM #temp1 b
WHERE #Grup1.id = b.id
Delete from #Grup1 where Data_ADD>@data
Select * from #Grup1
union
Select Old_ID,Centrala,ID_Grup,Pi, Ci, Pmt, Pneta, Rpp, Pd, UD, Suport1,Suport2, Suport3, Stare, Motiv,
Observatii, Comentarii, Un, Data_ADD, Modified_Date, Scada, Fuel_base From DeletedGrupuri where Deleted<=@Data and Old_ID is not null order by ID
drop table #temp
drop table #temp1
drop table #Grup1
如果有人有更好的解决方案或者可以改进此代码,请帮助我。此外,我还可以修改表Audit的设计以简化此过程。 谢谢!