ora_rowscn 伪列
如果你需要对表中每条数据的改动,做审计跟踪的话大概有以下两种方式。
一、在表中添加额外的列来存放表中某条记录的改动时间。并确保对数据的改动,必须往表中存放记录改动时间的字段填充时间值。
二、简单的使用oracle 提供的ora_rowscn 伪列,来获得表中每条记录大概的改动时间。第一种方式稍微复杂些,需要运用程序中代码的配合。下面介绍ora_rowscn 的使用。
SQL> create table norowdependencies_tab(
2 tim timestamp,
3 num number
4 ) norowdependencies;
Table created.
如果表创建的时候指定为 norowdependencies ,那么当使用ora_rowscn 伪列的时候,同一个db block 中的记录将会返回相同的 scn,也就是说修改时间在一个块内是相同的。默认表的属性就是这种方式,norowdependencies。
SQL> create table rowdependencies_tab(
2 tim timestamp,
3 num number
4 ) rowdependencies;
Table created.
如果表创建的时候指定为 rowdependencies ,那么当使用ora_rowscn 伪列的时候,将会将会返回记录级的scn 。
SQL> begin
2 for i in 1 .. 10 loop
3 insert into rowdependencies_tab values(systimestamp,i);
4 insert into norowdependencies_tab values(systimestamp,i);
5 commit;
6 dbms_lock.sleep(1);
7 end loop;
8 end;
9 /
PL/SQL procedure successfully completed.
SQL> select ora_rowscn,scn_to_timestamp(ora_rowscn) scn,tim
2 from norowdependencies_tab;
ORA_ROWSCN SCN TIM
---------- ---------------------------------------- ----------------------------------------
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.47.352000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.48.383000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.49.383000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.50.384000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.51.386000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.52.386000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.53.387000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.54.397000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.55.397000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.56.398000 下午
10 rows selected.
因为表norowdependencies 的属性是设置为norowdenpendencies 的,所以使用ora_rowscn 在同一个db block 中的记录将会返回相同的值,通过scn_to_timestamp 函数格式化输出以后也会得到相同的scn 时间戳。
SQL> select ora_rowscn,scn_to_timestamp(ora_rowscn) scn,tim
2 from rowdependencies_tab;
ORA_ROWSCN SCN TIM
---------- ---------------------------------------- ---------------------------------------
2874521 28-5月 -12 02.24.47.000000000 下午 28-5月 -12 02.24.45.652000 下午
2874523 28-5月 -12 02.24.47.000000000 下午 28-5月 -12 02.24.48.383000 下午
2874525 28-5月 -12 02.24.47.000000000 下午 28-5月 -12 02.24.49.383000 下午
2874527 28-5月 -12 02.24.47.000000000 下午 28-5月 -12 02.24.50.384000 下午
2874529 28-5月 -12 02.24.50.000000000 下午 28-5月 -12 02.24.51.386000 下午
2874531 28-5月 -12 02.24.50.000000000 下午 28-5月 -12 02.24.52.386000 下午
2874533 28-5月 -12 02.24.50.000000000 下午 28-5月 -12 02.24.53.387000 下午
2874535 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.54.397000 下午
2874537 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.55.397000 下午
2874539 28-5月 -12 02.24.53.000000000 下午 28-5月 -12 02.24.56.398000 下午
10 rows selected.
因为表rowdependencies 的属性是设置为rowdenpendencies 的,所以跟踪到的是db block 中记录级的scn。另外需要注意的是scn_to_timestamp 函数将会把间隔3 秒内的scn 转化为相同的时间戳。这一点从上面的查询中可以清楚的看到。这也是我们加dbms_lock.sleep(1) 的目的。