有一个表存储审计历史记录,即每当对主表执行插入,更新,删除操作时,相应的详细信息都存储在审计表中。
审计表的例子:
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应为null,如果“更新”,则应显示正在更新的列。
答案 0 :(得分: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;