当前位置: 首页 > Oracle, oracle 10g, oracle 11g > 正文

ORACLE查询表最近更改的数据

之前写过一篇关于利用闪回和logmgr找回被误删除数据的文章(详见http://www.dbdream.com.cn/2011/10/18/%E5%88%A9%E7%94%A8%E9%97%AA%E5%9B%9E%E5%92%8Clogmnr%E6%89%BE%E5%9B%9E%E8%AF%AF%E5%88%A0%E9%99%A4%E6%95%B0%E6%8D%AE),今天开发人员问我如何快速并方便的查出一张表最近被更改的记录,这个需求很简单,由于是查最近被更改的数据,查回滚段就可以,下面是我做的小实验。

SQL> create table test(id number,name varchar2(10),gender varchar2(5));

表已创建。
SQL> insert into test values(1,'宋春风','男');

已创建 1 行。
SQL> insert into test values(2,'叶民','男');

已创建 1 行。
SQL> insert into test values(3,'白冰','男');

已创建 1 行。
SQL> insert into test values(4,'方巍森','男');

已创建 1 行。
SQL> insert into test values(5,'孙书祯','男');

已创建 1 行。
SQL> insert into test values(6,'史波','男');

已创建 1 行。

SQL> commit;

提交完成。

利用下面的SQL就可以查处最近更改的数据。

SQL> SELECT ID,NAME,VERSIONS_STARTTIME,VERSIONS_ENDTIME,VERSIONS_OPERATION
FROM TEST VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE WHERE
VERSIONS_STARTTIME IS NOT NULL ORDER BY VERSIONS_STARTTIME DESC;

        ID NAME   GENDE VERSIONS_STARTTIME        VERSIONS_ENDTIME          V
---------- ------ ----- ------------------------- ------------------------- -
         6 史波   男    30-11月-11 04.02.28 下午                            I
         5 孙书祯 男    30-11月-11 04.02.28 下午                            I
         1 宋春风 男    30-11月-11 04.02.28 下午                            I
         3 白冰   男    30-11月-11 04.02.28 下午                            I
         2 叶民   男    30-11月-11 04.02.28 下午                            I
         4 方巍森 男    30-11月-11 04.02.28 下午                            I

已选择6行。

修改几条数据和接下来的查询做对比。

SQL> UPDATE TEST SET GENDER='女' WHERE NAME='孙书祯';

已更新 1 行。
SQL> COMMIT;

提交完成。
SQL> UPDATE TEST SET GENDER='女' WHERE NAME='史波';

已更新 1 行。
SQL> COMMIT;

提交完成。

再次查询,被修改的数据就可以看到被修改和修改前的数据。

SQL> SELECT ID,NAME,GENDER,VERSIONS_STARTTIME,VERSIONS_ENDTIME,
VERSIONS_OPERATION FROM TEST VERSIONS BETWEEN TIMESTAMP MINVALUE AND
MAXVALUE WHERE VERSIONS_STARTTIME IS NOT NULL ORDER BY
VERSIONS_STARTTIME DESC;

        ID NAME   GENDE VERSIONS_STARTTIME        VERSIONS_ENDTIME          V
---------- ------ ----- ------------------------- ------------------------- -
         6 史波   女    30-11月-11 04.15.07 下午                            U
         5 孙书祯 女    30-11月-11 04.14.31 下午                            U
         4 方巍森 男    30-11月-11 04.02.28 下午                            I
         3 白冰   男    30-11月-11 04.02.28 下午                            I
         2 叶民   男    30-11月-11 04.02.28 下午                            I
         1 宋春风 男    30-11月-11 04.02.28 下午                            I
         6 史波   男    30-11月-11 04.02.28 下午  30-11月-11 04.15.07 下午  I
         5 孙书祯 男    30-11月-11 04.02.28 下午  30-11月-11 04.14.31 下午  I

已选择8行。

再修改几条数据后后查询。

SQL> delete from test WHERE NAME='史波';

已删除 1 行。
SQL> delete from test WHERE NAME='孙书祯';

已删除 1 行。
SQL> commit;

提交完成。
SQL> SELECT ID,NAME,GENDER,VERSIONS_STARTTIME,VERSIONS_ENDTIME,
VERSIONS_OPERATION FROM TEST VERSIONS BETWEEN TIMESTAMP MINVALUE AND
MAXVALUE WHERE VERSIONS_STARTTIME IS NOT NULL ORDER BY
VERSIONS_STARTTIME DESC;

        ID NAME   GENDE VERSIONS_STARTTIME        VERSIONS_ENDTIME          V
---------- ------ ----- ------------------------- ------------------------- -
         5 孙书祯 男    30-11月-11 04.26.02 下午                            D
         6 史波   男    30-11月-11 04.26.02 下午                            D
         6 史波   女    30-11月-11 04.15.07 下午  30-11月-11 04.19.08 下午  U
         5 孙书祯 女    30-11月-11 04.14.31 下午  30-11月-11 04.19.08 下午  U
         2 叶民   男    30-11月-11 04.02.28 下午                            I
         3 白冰   男    30-11月-11 04.02.28 下午                            I
         4 方巍森 男    30-11月-11 04.02.28 下午                            I
         5 孙书祯 男    30-11月-11 04.02.28 下午  30-11月-11 04.14.31 下午  I
         1 宋春风 男    30-11月-11 04.02.28 下午                            I
         6 史波   男    30-11月-11 04.02.28 下午  30-11月-11 04.15.07 下午  I

已选择10行。

通过以上小实验可以看出,VERSIONS_STARTTIME是数据被修改的起始时间,VERSIONS_ENDTIME是数据被修改后新数据的有效时间,也就是VERSIONS_STARTTIME和VERSIONS_ENDTIME时间段内,这条数据再没被修改过,如果VERSIONS_ENDTIME为空,就说明这天记录从VERSIONS_STARTTIME时间起再没被修改过。VERSIONS_OPERATION是修改状态,I代表INSERT,U代表UPDATE,D代表DELETE。此时如果想回滚INSERT的数据,只需要DELETE反向操作即可,如果想回滚UPDATE操作,将数据反向UPDATE回去即可,比如本实验已经可以看到进行UPDATE操作的是NAME为史波和孙书祯的两条记录,而且也可以看到进行UPDATE之前的数据他们的性别是男,所以只需要在做个反向UPDATE,将性别该为男即可实现回退,如果要回滚DELETE操作,同样做个INSERT操作,将删除的数据在插回去即可。
注:此SQL只能查询到回滚段内的信息,超出回滚段范围这个SQL就无能为力了,需要借助LOGMGR工具挖掘日志了(详见http://www.dbdream.com.cn/2011/10/18/%E5%88%A9%E7%94%A8%E9%97%AA%E5%9B%9E%E5%92%8Clogmnr%E6%89%BE%E5%9B%9E%E8%AF%AF%E5%88%A0%E9%99%A4%E6%95%B0%E6%8D%AE/)。

本文固定链接: http://www.dbdream.com.cn/2011/12/oracle%e6%9f%a5%e8%af%a2%e8%a1%a8%e6%9c%80%e8%bf%91%e6%9b%b4%e6%94%b9%e7%9a%84%e6%95%b0%e6%8d%ae/ | 信春哥,系统稳,闭眼上线不回滚!

该日志由 dbdream 于2011年12月01日发表在 Oracle, oracle 10g, oracle 11g 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: ORACLE查询表最近更改的数据 | 信春哥,系统稳,闭眼上线不回滚!
关键字:

ORACLE查询表最近更改的数据:目前有1 条留言

  1. 沙发
    Anastacia:

    Useful know-how! I have been looking for everything like that for a time now. Thanks!

    2011-12-07 22:46 [回复]

发表评论

快捷键:Ctrl+Enter