2016-08-22 58 views
0

我遇到了与此处相关的相同问题Building a snapshot table from audit records。下面的代码部分解决了我的问题从ms审计跟踪构建快照表sql

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)<[email protected]) 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, 

和审计表的结构是:

[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'用于更新,插入和删除操作。另一个问题是,如果审计表包含对主表中的行的修改,并且快照的日期低于审计中的updateDate,那么我必须选择OldValue else NewValue。它是正确的? 谢谢@ Nick.McDermaid的回复!

+0

您是否想要始终查看表格的最新视图或是否需要在任何特定时间查看该表格?您只需将审核行应用到原始记录即可。你会在特殊的独立表格中生成快照吗?请发布它的DDL –

回答

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) <[email protected]) 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<[email protected] and Old_ID is not null order by ID 
    drop table #temp 
    drop table #temp1 
    drop table #Grup1 

如果有人有更好的解决方案,也可以改善这个代码,请帮助我。此外,我愿意修改表审计的设计以简化此过程。 谢谢!