oracle的rowid是记录行的唯一标识,一般会包含相对文件号、块号、槽号(块内序号)的信息。其值的含义可参见官方文档。在一些技术blog上也有详细的描述,如http://zhouwf0726.itpub.net/post/9689/196733和http://blog.oracle.com.cn/index.php/12012/action_viewspace_itemid_4684.html中。也可以自己动手花几分钟写个小程序进行rowid的解析。
-- 调用系统存储过程,解析rowid
begin
-- Call the procedure
sys.dbms_rowid.rowid_info(rowid_in => :rowid_in,
rowid_type => :rowid_type,
object_number => :object_number,
relative_fno => :relative_fno,
block_number => :block_number,
row_number => :row_number);
end;
-- 自己编写的rowid解析程序(代码较简单,不妨作些指令优化提高字符串操作的性能)
/*
Restricted Rowid
----------------------------------------
| BBBBBBBB . RRRR . FFFF |
------------------------------------------
/ / /
| | |
| | --------------------File Number
| ------------------------------Row Number
--------------------------------------------Block NumberOracle 8 Rowid
------------------------------------------------
| OOOOOO . FFF . BBBBBB . SSS |
------------------------------------------------
/ / / /
| | | |
| | | -----------Slot Number(Row#)
| | ----------------------Block Number
| --------------------------------Relative File Number
----------------------------------------------Data Object Numberrowid的定义规则,第7~9位是表示的是数据文件,而10~15位表示的是在这个数据文件中的第几个BLOCK。
rowid编码相当于64进制。用A~Z a~z 0~9 + /共64个字符表示。A表示0,B表示1,...,a表示26,...,0表示52,...,+表示62,/表示63。)
*/
declare
-- 局部变量定义
i integer;
input VARCHAR2(100);
pat VARCHAR2(64) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
slot# INTEGER := 0;
blk# INTEGER := 0;
relfno# INTEGER := 0;
obj# INTEGER := 0;
ch CHAR(1);
n INTEGER;
begin
-- 测试用的rowid值,可提取为输入参数
input := 'AAAJrBAAMAAD4rmAAA';
-- 根据字符位置以及64进制,进行计算
FOR i IN 1..6 LOOP
ch := substr(input, i, 1);
n := instr(pat, ch) - 1;
obj# := obj# * 64 + n;
END LOOP;
FOR i IN 7..9 LOOP
ch := substr(input, i, 1);
n := instr(pat, ch) - 1;
relfno# := relfno# * 64 + n;
END LOOP;
FOR i IN 10..15 LOOP
ch := substr(input, i, 1);
n := instr(pat, ch) - 1;
blk# := blk# * 64 + n;
END LOOP;
FOR i IN 16..18 LOOP
ch := substr(input, i, 1);
n := instr(pat, ch) - 1;
slot# := slot# * 64 + n;
END LOOP;
dbms_output.put_line('(object_number, relative_fno, block_number, row_number)');
dbms_output.put_line('(' || obj# || ', ' || relfno# || ', ' || blk# || ', ' || slot# || ')');
end;
/