除了之前提到的,START_LOGMNR、ADD_LOGFILE和END_LOGMNR以外呢,DBMS_LOGMNR包还有以下这些函数可以配合在Logminer中使用:
mine_value(redo_value/undo_value,'schema.table.column') 这是这个包中的一个函数,整个函数将返回一个值,这个值就是指定的用户的某个表的某列redo信息中的或者undo信息中的值,第一个参数指定的就是Logminer搜索的范围是redo还是undo,那可以想到,因为在该列被insert之前的值应该是null,同理在delete之后的值应该是null,所以如果是insert那应该只有redo信息返回not null值,而delete应该只是undo信息返回not null值,update则都是可以有,只不过两个值不同。第二个参数就是指定某个用户的某个表的某列,那这个函数可以很方便的帮我们筛选出我们想要的值。
- SQL> insert into logmnr_test values (2);
- 1 row created.
- SQL> insert into logmnr_test values (3);
- 1 row created.
- SQL> delete from logmnr_test where id = 2;
- 1 row deleted.
- SQL> commit;
- Commit complete.
- SQL> select sql_redo,nvl(dbms_logmnr.mine_value(redo_value,'sys.logmnr_test.id'),-1) redo_value, nvl(dbms_logmnr.mine_value(undo_value,'sys.logmnr_test.id'),-1) undo_value from v$logmnr_contents where table_name='LOGMNR_TEST';
- SQL_REDO
- --------------------------------------------------------------------------------
- REDO_VALUE
- --------------------------------------------------------------------------------
- UNDO_VALUE
- --------------------------------------------------------------------------------
- insert into "SYS"."LOGMNR_TEST"("ID") values ('2');
- 2
- -1
- insert into "SYS"."LOGMNR_TEST"("ID") values ('3');
- 3
- -1
- SQL_REDO
- --------------------------------------------------------------------------------
- REDO_VALUE
- --------------------------------------------------------------------------------
- UNDO_VALUE
- --------------------------------------------------------------------------------
- delete from "SYS"."LOGMNR_TEST" where "ID" = '2' and ROWID = 'AAAR7lAABAAAU3JAAB
- ';
- -1
- 2
从上面这个例子可以看到,mine_value中的redo和undo参数产生的不同结果,和我们的理论符合,那用这个函数配合在where当中限制,就可以过滤出我们需要的行,例如
- SQL> select sql_redo,dbms_logmnr.mine_value(redo_value,'sys.logmnr_test.id') value from v$logmnr_contents where table_name='LOGMNR_TEST' and dbms_logmnr.mine_value(redo_value,'sys.logmnr_test.id') = 2;
- SQL_REDO
- --------------------------------------------------------------------------------
- VALUE
- --------------------------------------------------------------------------------
- insert into "SYS"."LOGMNR_TEST"("ID") values ('2');
- 2
那再假设,我们insert了一行,指定的列是null,我们又删除了一列,而我只想查看到新值为null的那个redo也就是insert,显然,再用原来的过滤方式不行了。
所以配合mine_value函数还有column_present可以配合使用,column_present的参数和mine_value完全一致,如果指定列的值本来就是null而不是由insert或者redo生成的,那这个函数会返回1,否则会返回0,我们
- SQL> select sql_redo from v$logmnr_contents where table_name='LOGMNR_TEST' and dbms_logmnr.mine_value(redo_value,'sys.logmnr_test.id') is null;
- SQL_REDO
- --------------------------------------------------------------------------------
- insert into "SYS"."LOGMNR_TEST"("ID") values (NULL);
- delete from "SYS"."LOGMNR_TEST" where "ID" = '3' and ROWID = 'AAAR7lAABAAAU3JAAC
- ';
- SQL> select sql_redo from v$logmnr_contents where table_name='LOGMNR_TEST' and dbms_logmnr.mine_value(redo_value,'sys.logmnr_test.id') is null and dbms_logmnr.column_present(redo_value,'sys.logmnr_test.id') = 1;
- SQL_REDO
- --------------------------------------------------------------------------------
- insert into "SYS"."LOGMNR_TEST"("ID") values (NULL);
可以看下实验结果,成功只筛选出了insert语句。
那DBMS_LOGMNR的包主要就这点内容了,希望能对大家有所帮助。
转载于:https://blog.51cto.com/oxiaobai/740294