DBMS_ROWID是一个比较有用的系统自带的package,主要可以用来处理坏块的问题,于是仔细的研究了一下,这个包可以用来了解file、block、object id和rowid之间的关系,在Oracle8中被引用进来,Oracle7不支持这个包。这个包的定义可以在dbmsutil.sql中找到,在catproc.sql中被调用,并被给予public执行权限。
首先来了解一下这个包中使用的常量:
ROWID
类型:
rowid_type_restricted RESTRICTED - Restricted ROWID
rowid_type_extended EXTENDED - Extended ROWID
ROWID
验证结果:
rowid_is_valid VALID - Valid ROWID
rowid_is_invalid INVALID - Invalid ROWID
目标类型:
rowid_object_undefined UNDEFINED - Object Number not defined (for restricted ROWIDs)
ROWID
转换类型:
rowid_convert_internal INTERNAL - convert to/from column of ROWID type
rowid_convert_external EXTERNAL - convert to/from string format
意外错误:
ROWID_INVALID invalid rowid format
ROWID_BAD_BLOCK block is beyond end of file
在DBMS_ROWID这个包里面可以使用下面的功能:
function ROWID_CREATE(rowid_type IN number,
object_number IN number,
relative_fno IN number,
block_number IN number,
row_number IN number)
return ROWID;
-- rowid_type -
类型(restricted=0/extended=1)
-- object_number -
对象号
-- relative_fno - relative file number
-- block_number -
文件包含的block号
-- row_number - block
中的行的行号
下面具体的讨论一下DBMS_ROWID包的用法:
1. DBMS_ROWID.ROWID_BLOCK_NUMBER:
返回一个rowid的block号
定义如下:
function dbms_rowid.rowid_block_number
(row_id in rowid)
return number
SQL> select dbms_rowid.rowid_block_number(rowid) "block" from test;
block
----------
23722
2. DBMS_ROWID.ROWID_CREATE:
创建并返回一个基于单独行的rowid,创建的rowid类型是RESTRICTED或者是EXTENDED,这种功能一般都是用于测试目的,因为只有oracle才能创建一个合法的rowid指向数据。
定义如下:
function dbms_rowid.rowid_create
(rowid_type in number
,object_number in number
,relative_fno in number
,block_number in number
,row_number in number)
return rowid
例子:
创建一个restricted rowid
:
SQL> select dbms_rowid.rowid_create(0, 6877,1,23722,0) from dual;
DBMS_ROWID.ROWID_C
------------------
00005CAA.0000.0001
创建一个extended rowid:
SQL> select dbms_rowid.rowid_create(1, 6877,1,23722,0) from dual;
DBMS_ROWID.ROWID_C
------------------
AAABrdAABAAAFyqAAA
3. DBMS_ROWID.ROWID_INFO:
返回一个单独组件的一个指定的rowid,它只能用于PL/SQL,而不能用于sql语句中。
定义如下:
procedure dbms_rowid.rowid_info
(rowid_in in rowid
,rowid_type out number
,object_number out number
,relative_fno out number
,block_number out number
,row_number out number)
例子:
SQL> set serverout on
SQL> set echo on
SQL> declare
2 my_rowid rowid;
3 rowid_type number;
4 object_number number;
5 relative_fno number;
6 block_number number;
7 row_number number;
8 begin
9 my_rowid :=dbms_rowid.rowid_create(1, 6877,1,23722,0);
10 dbms_rowid.rowid_info(my_rowid, rowid_type, object_number,
11 relative_fno, block_number, row_number);
12 dbms_output.put_line('ROWID: ' || my_rowid);
13 dbms_output.put_line('Object#: ' || object_number);
14 dbms_output.put_line('RelFile#: ' || relative_fno);
15 dbms_output.put_line('Block#: ' || block_number);
16 dbms_output.put_line('Row#: ' || row_number);
17 end;
18 /
ROWID: AAABrdAABAAAFyqAAA
Object#: 6877
RelFile#: 1
Block#: 23722
Row#: 0
PL/SQL
过程已成功完成。
4.DBMS_ROWID.ROWID_OBJECT:
返回一个rowid的对象号。如果是restricted 的rowid,则返回0。
定义如下:
function dbms_rowid.rowid_object
(row_id in rowid)
return number
例子:
SQL> select dbms_rowid.rowid_object(rowid) "OBJECT" from test;
OBJECT
----------
6877
SQL> select dbms_rowid.rowid_object(dbms_rowid.rowid_to_restricted(rowid,0)) " OBJECT " from test;
OBJECT
----------
0
5. DBMS_ROWID.ROWID_RELATIVE_FNO:
返回一个rowid的相对文件号。
定义如下:
function dbms_rowid.rowid_relative_fno
(row_id in rowid)
return number
例子:
SQL> select dbms_rowid.rowid_relative_fno(rowid) "relative fno" from test;
relative fno
------------
1
6. DBMS_ROWID.ROWID_ROW_NUMBER:
返回一个rowid的行号。(从零开始)
定义如下:
function dbms_rowid.rowid_row_number
(row_id in rowid)
return number
例子:
SQL> select dbms_rowid.rowid_row_number(rowid) "row" from test;
row
----------
0
7. DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO
:返回一个rowid的完全文件号。
定义如下:
function dbms_rowid.rowid_to_absolute_fno
(rowid in rowid
,schema_name in varchar2
,object_name in varchar2)
return number
例子:
SQL> select dbms_rowid.rowid_to_absolute_fno (rowid, 'SYS', 'TEST') "absolute fno" from test;
absolute fno
------------
1
8. DBMS_ROWID.ROWID_TO_EXTENDED:
转换一个restricted rowid为一个extended rowid.如果原始的rowid存储在列中,转换的 就是internal类型;如果原始的rowid是以字符串形式存储的,那转换的就是external类型。
定义如下:
function dbms_rowid.rowid_to_extended
(old_rowid in rowid
,schema_name in varchar2
,object_name in varchar2
,conversion_type in integer)
return rowid
例子:
转换restricted internal rowid为extended格式
SQL>select dbms_rowid.rowid_to_extended (dbms_rowid.rowid_to_restricted(rowid,0),'SYS','TEST',0) "extended rowid" from test;
extended rowid
------------------
AAABrdAABAAAFyqAAA
转换restricted external rowid为extended格式
SQL> select dbms_rowid.rowid_to_extended ('00005CAA.0000.0001','SYS','TEST',1) from dual;
DBMS_ROWID.ROWID_T
------------------
AAABrdAABAAAFyqAAA
如果参数中的SCHEMA和OBJECT为null,则默认是当前的对象
SQL>select dbms_rowid.rowid_to_extended (dbms_rowid.rowid_to_restricted(rowid,0),null,null,0) "extended rowid" from test;
extended rowid
------------------
AAABrdAABAAAFyqAAA
9. DBMS_ROWID.ROWID_TO_RESTRICTED:
转换一个exteneded的rowid为一个restricted的rowid,restricted的rowid格式为BBBBBBB.RRRR.FFFFF, BBBBBBB代表block,RRRR 代表在block中的行号,从0开始,FFFFF代表文件号。这个包可以使用rowid或者rowid转换类型(ROWID_CONVERT_INTERNAL (0)和ROWID_CONVERT_EXTERNAL (1))
定义如下:
function dbms_rowid.rowid_to_restricted
(old_rowid in rowid
,conversion_type in integer)
return rowed
例子:
SQL> select dbms_rowid.rowid_to_restricted(rowid, 1) "restricted rowid" from test;
restricted rowid
------------------
00005CAA.0000.0001
Block
计算:5*16*16*16+C*16*16+A*16+A=20480+3072+160+10=23722
10
.DBMS_ROWID.ROWID_TYPE:返回rowid的类型,ROWID_TYPE_RESTRICTED(0)和ROWID_TYPE_EXTENDED(1)。
定义如下:
function dbms_rowid.rowid_type
(row_id in rowid)
return number;
例子:
Oracle8
以后的版本的rowid都是extended类型
SQL> select dbms_rowid.rowid_type(rowid) "type" from test;
type
----------
1
Oracle7
的rowid是restricted类型
SQL> select dbms_rowid.rowid_type(chartorowid('00005CAA.0000.0001')) "type" from dual;
type
----------
0
11.DBMS_ROWID.ROWID_VERIFY:
验证一个restricted的rowid是否能够转换成extended的rowid,它可以用来发现存在问题的rowid。
定义如下:
function rowid_verify(rowid_in IN rowid,
schema_name IN varchar2,
object_name IN varchar2,
conversion_type IN integer)
return number;
介绍了这个包的用法后,其实对于我们最主要的还是利用DBMS_ROWID.ROWID_CREATE
来解决坏块的一些问题,下面举一个具体如何使用这个包来解决坏块的例子。
SQL> create tablespace test datafile 'd:oracleoradataorcltest.dbf' size 5M;
表空间已创建。
SQL> create user coolyl identified by coolyl
2 default tablespace test
3 temporary tablespace temp;
用户已创建。
SQL> grant connect,resource,dba to coolyl;
授权成功。
SQL> connect coolyl/coolyl
已连接。
SQL> create table test as select * from dba_objects;
表已创建。
SQL> insert into test select * from test;
已创建6238行。
SQL> insert into test select * from test;
from:http://space.itpub.net/3704/viewspace-488900