使用DBMS_REPAIR包修复损坏数据块
3、使用P_DUMPROWID恢复数据的例子
下面再简单说明一下这个程序包是如何恢复其他数据类型的。
通过查询ORPHAN_KEY_TABLE可以发现,Oracle把索引的值保存在逻辑ROWID中,我这个包实现的其实就是将逻辑ROWID中的值还原为索引键值。下面的例子为了简单起见,通过建立索引组织表,然后使用这个包还原索引组织表的ROWID信息作为参考的例子。
例1:对NUMBER类型、VARCHAR2类型和TIME类型的恢复,对复合索引的恢复。
SQL> create table test_index (id number, name varchar2(30), time date,
2 constraint pk_test_index primary key (id, name, time))
3 organization index;
表已创建。
SQL> insert into test_index select rownum, object_name, created from user_objects;
已创建64行。
SQL> commit;
提交完成。
SQL> col dump format a30
SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> select id, p_dumprowid.f_dump_from_rowid(ROWID, 'YANGTK', 'PK_TEST_INDEX') dump
2 from test_index where rownum < 5;
ID DUMP
---------- ------------------------------
1 1
2 2
3 3
4 4
SQL> select name, p_dumprowid.f_dump_from_rowid(ROWID, 'YANGTK', 'PK_TEST_INDEX', 2) dump
2 from test_index where rownum < 5;
NAME DUMP
------------------------------ ------------------------------
AA AA
IND_Q1_ID IND_Q1_ID
IND_Q1_ID IND_Q1_ID
IND_Q1_ID IND_Q1_ID
SQL> select time, p_dumprowid.f_dump_from_rowid(ROWID, 'YANGTK', 'PK_TEST_INDEX', 3) dump
2 from test_index where rownum < 5;
TIME DUMP
------------------- ------------------------------
2004-12-19 02:36:33 2004-12-19 2:36:33
2004-12-18 23:17:56 2004-12-18 23:17:56
2004-12-18 23:17:56 2004-12-18 23:17:56
2004-12-18 23:18:33 2004-12-18 23:18:33
例二:对TIMESTAMP类型的恢复。
SQL> create table test_stamp (time timestamp constraint pk_test_stamp primary key)
2 organization index;
表已创建。
SQL> insert into test_stamp values (systimestamp);
已创建 1 行。
SQL> alter session set nls_timestamp_format = 'yyyy-mm-dd hh24:mi:ss.ff';
会话已更改。
SQL> col dump format a40
SQL> col time format a40
SQL> select time, p_dumprowid.f_dump_from_rowid(rowid, 'YANGTK', 'PK_TEST_STAMP') dump
2 from test_stamp;
TIME DUMP
---------------------------------------- ----------------------------------------
2005-01-13 00:44:27.392000 2005-1-13 0:44:27.392000
SQL> alter table test_stamp modify (time timestamp(9));
表已更改。
SQL> insert into test_stamp values (to_timestamp('2005-1-1 12:23:23.334282122',
2 'yyyy-mm-dd hh24:mi:ss.ff'));
已创建 1 行。
SQL> select time, p_dumprowid.f_dump_from_rowid(rowid, 'YANGTK', 'PK_TEST_STAMP') dump
2 from test_stamp;
TIME DUMP
---------------------------------------- ----------------------------------------
2005-01-01 12:23:23.334282122 2005-1-1 12:23:23.334282122
2005-01-13 00:44:27.392000000 2005-1-13 0:44:27.392000000
![]()
这个包可以支持普通的单列BTREE索引和复合BTREE索引,不支持reverse key索引和BITMAP索引。
目前支持的数据类型包括CHAR、VARCHAR2、NUMBER、DATE、TIMESTAMP、RAW和物理ROWID类型。这个包不支持的类型包括NCHAR、NVARCHAR2、TIMESTAMP WITH LOCAL TIME ZONE和TIMESTAMP WITH TIME ZONE等几种不很常用的类型(LONG、LONG RAW、逻辑ROWID和LOB类型不支持索引)。
如果VARCHAR2(CHAR)类型中包含中文,在ZHS16GBK字符集下我测试通过,其他字符集没有测试,但估计对于一般中文字符集都不会有问题,但是如果用单字节字符集表示中文可能会有问题。
任何一个工具也不可能只有好的方面而没有任何缺点。使用DBMS_REPAIR包的同时会带来数据丢失、表和索引返回数据不一致,完整性约束破坏等问题。因此当出现错误时,首先应当考虑用物理备份或逻辑备份进行恢复,DBMS_REPAIR包应该只是在没有备份的情况下使用的一种手段。DMBS_REPAIR包无法恢复表中没有被索引的列,因此使用这种方式一般都会造成数据的丢失。
参考文档:
1. Oracle9i Administrator’s Guide
2. Oracle9i Database Concepts
3. Supplied PL/SQL Packages and Types Reference
我在ITPUB上的这篇帖子包括了对Oracle基本数据类型的描述:
http://www.itpub.net/308317.html
