0

有一个表存储审计历史,即每当对主表执行插入、更新、删除操作时,相应的详细信息都存储在审计表中。

审计表示例:

eid ename   designation age username           datemodified     flag
10  arjun   jnr sqldeveloper    25  SGA\username    26:14.0          Inserted
11  bala    jnr sqldeveloper    21  SGA\username    26:20.9          Inserted
12  chandra jnr sqldeveloper    21  SGA\username    26:28.7          Inserted
10  arjun   snr sqldeveloper    25  SGA\username    26:40.0         updatedvalue
11        bala      jnr sqldeveloper     21        SGA\username        26:40.0            Deleted
10        arjun     snr sqldeveloper     27 SGA\username        26:40.0          updatedvalue 

如果执行更新:

update mastertable
set ename='arjun'
    designation='snr sqldeveloper'
    age=27
where eid=10    

请注意,只有名为 age 的列正在被修改。

我需要一个以以下格式显示输出的过程:

eid  ename    designation   age username        datemodified  flag        modified_column
10   arjun    jnr sqldeveloper  25  SGA\username  26:14.0       Inserted       Null
11   bala   jnr sqldeveloper   21        SGA\username   26:40.0       Deleted        Null
10   arjun  snr sqldeveloper    27  SGA\username  26:40.0       updatedvalue    age

如果标志是“插入或删除”,modified_column 应该为空,如果它是“更新”,则应该显示正在更新的列。

4

1 回答 1

0

这可能会给你一些想法:

declare @Stuff as Table ( StuffId Int Identity, Age Int, ShoeSize VarChar(10) );
insert into @Stuff ( Age, ShoeSize ) values
  ( 10, '8' ), ( 12, '9W' ), ( 16, '12EE' );
select * from @Stuff;

-- Assumption: The audit table includes all activity from the beginning of time.
-- Note that order of activities is provided by the StuffAuditId column rather than using ActivityTime.
--   This avoids problems when multiple activities occur within one tick of Ye Olde Clock.
declare @StuffAudit as Table ( StuffAuditId Int Identity, Activity Char(1), ActivityTime DateTime, StuffId Int, Age Int, ShoeSize VarChar(10) );
insert into @StuffAudit ( Activity, ActivityTime, StuffId, Age, ShoeSize ) values
  ( 'I', '20130101 00:00:00', 1, 10, '7' ),
  ( 'I', '20130101 00:00:00', 2, 12, '9W' ),
  ( 'I', '20130101 00:00:00', 3, 16, '12' ),
  ( 'U', '20130101 00:00:00', 1, 10, '8' ),
  ( 'U', '20130101 00:00:42', 3, 15, '12' ),
  ( 'D', '20130101 01:00:00', 4, 2, '4' ),
  ( 'U', '20130107 01:00:00', 1, 11, '8N' );
select * from @StuffAudit;

-- Assumption: The data columns being tested for changes do not allow NULLs.
select Activity, ActivityTime, StuffId, Age, ShoeSize,
  case when Len( ModifiedColumn ) > 2 then Substring( ModifiedColumn, 3, Len( ModifiedColumn ) - 2 ) else ModifiedColumn end as ModifiedColumn
  from (
    -- Insert and Delete activity goes straight to the report.
    select *, NULL as ModifiedColumn
      from @StuffAudit
      where Activity in ( 'I', 'D' )
    union all
    -- For each Update match it to the most recent Insert or Update for the same row.
    select SA.*,
      ( case when SA.Age <> OldSA.Age then ', Age' else '' end +
      case when SA.ShoeSize <> OldSA.ShoeSize then ', ShoeSize' else '' end )
      from @StuffAudit as SA left outer join
        @StuffAudit as OldSA on OldSA.StuffAuditId =
          ( select Max( StuffAuditId ) from @StuffAudit where StuffAuditId < SA.StuffAuditId and StuffId = SA.StuffId and Activity in ( 'I', 'U' ) )
      where SA.Activity = 'U'
       ) as Leonard
  order by ActivityTime, StuffAuditId, StuffId;
于 2013-11-05T18:56:21.873 回答