首先创建一个测试表
SQL> conn /as sysdba
已连接。
SQL> select file_name from dba_data_files;
FILE_NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/users01.dbf
/u01/app/oracle/oradata/orcl/sysaux01.dbf
/u01/app/oracle/oradata/orcl/undotbs01.dbf
/u01/app/oracle/oradata/orcl/system01.dbf
SQL> create tablespace tb1 datafile '/u01/app/oracle/oradata/orcl/tb1.dbf' size 10m;
表空间已创建。
SQL> create user u1 identified by u1 default tablespace tb1;
用户已创建。
SQL> grant connect,resource to u1;
授权成功。
SQL> conn u1/u1
已连接。
SQL> create table t(id int,value varchar2(10));
表已创建。
SQL> insert into t values(1,'a');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from t;
ID VALUE
---------- ----------
1 a
1 基于时间的查询(AS OF TIMESTAMP)
SQL> select sysdate from dual;
SYSDATE
-------------------
2011-10-18 06:14:06
SQL> insert into t values(2,'b');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from t;
ID VALUE
---------- ----------
1 a
2 b
SQL> select * from t as of timestamp to_date('2011-10-18 06:14:06','yyyy-mm-dd hh24:mi:ss');
ID VALUE
---------- ----------
1 a
SQL> select * from t as of timestamp sysdate-5/1440; --查询5分钟以前的数据
ID VALUE
---------- ----------
1 a
说明:60(分)×24=1440,这样就计算出一天拥有多少分钟。SYSDATE-5/1440,得出的就是距当前时间5分钟前的记录了。
2 基于SCN的查询(AS OF SCN)
SQL> conn /as sysdba
已连接。
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
474847
SQL> conn u1/u1
已连接。
SQL> insert into t values(3,'c');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from t;
ID VALUE
---------- ----------
1 a
2 b
3 c
SQL> select * from t as of scn 474847;
ID VALUE
---------- ----------
1 a
2 b
3 SCN和时间的对应关系
使用SCN查询会比TIMESTAMP更加精确,事实上,即使执行Flashback Query时指定的是AS OF TIMESTAMP,Oracle也会将其转换成SCN,这是由于Oracle内部都是通过SCN来标记操作而不是时间。
查询scn和时间的对应关系
SQL> conn /as sysdba
已连接。
SQL> select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from smon_scn_time;
SCN TO_CHAR(TIME_DP,'YY
---------- -------------------
4 2008-02-17 01:50:43
10725 2008-02-17 01:51:16
114369 2008-02-17 01:56:49
160566 2008-02-17 02:01:21
238143 2008-02-17 02:06:31
296479 2008-02-17 02:11:17
340068 2008-02-17 02:17:22
380836 2008-02-17 02:21:18
428625 2008-02-17 02:26:36
438655 2008-02-17 02:28:33
438698 2008-02-17 02:28:34
SCN TO_CHAR(TIME_DP,'YY
---------- -------------------
461085 2008-02-17 02:29:13
461400 2008-02-17 02:29:36
463047 2008-02-17 02:29:50
464634 2011-10-18 05:53:12
473110 2011-10-18 05:54:17
473423 2011-10-18 05:54:40
473499 2011-10-18 05:54:43
474181 2011-10-18 05:59:47
474185 2011-10-18 05:59:57
474286 2011-10-18 06:04:57
474635 2011-10-18 06:10:12
SCN TO_CHAR(TIME_DP,'YY
---------- -------------------
474735 2011-10-18 06:14:57
已选择23行。
把时间转换为scn
SQL> select timestamp_to_scn(sysdate) from dual;
TIMESTAMP_TO_SCN(SYSDATE)
-------------------------
474991
把scn转换为时间
SQL> select to_char(scn_to_timestamp(474991),'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SCN_TO_TIME
-------------------
2011-10-18 06:25:22
注意:如果SYS.SMON_SCN_TIME表中不存在时间和SCN的映射关系,则执行函数转换时就会报错,也就是说时间和SCN之间并不存在绝对的对应关系。一切都是Oracle提供给你的,只有当它愿意让你看,你才能够看到。