关于rowid的小小研究

rowid由4个部分组成:
第一部分:1-6位,标识对象即表 dbms_rowid.rowid_object返回object_id
第二部分:7-9位,标识数据文件 dbms_rowid.rowid_relative_fno返回rfile_id
第三部分:10-15位,标识数据块 dbms_rowid.rowid_block_number返回block_id
第四部分:16-18位,标识行在块的位置 dbms_rowid.rowid_row_number返回,值从0开始

如果你知道了上述4个部分的值,可以通过ROWID_CREATE函数组合成一个rowid

select t.*,
dbms_rowid.rowid_create(
1,object_id,rfile_id,block_id,row_no) cre_rowid
from (
select id,
dbms_rowid.rowid_object(rowid) object_id,
dbms_rowid.rowid_relative_fno(rowid) rfile_id,
dbms_rowid.rowid_block_number(rowid) block_id,
dbms_rowid.rowid_row_number(rowid) row_no,
rowid rid
from a) t;

ID OBJECT_ID RFILE_ID BLOCK_ID ROW_NO RID CRE_ROWID
---------- ---------- ---------- ---------- ---------- ------------------ ------------------
2 53057 4 110653 0 AAAM9BAAEAAAbA9AAA AAAM9BAAEAAAbA9AAA
3 53057 4 110653 1 AAAM9BAAEAAAbA9AAB AAAM9BAAEAAAbA9AAB

我们可以发现,rowid是由上述4部分数字以64进制组成,其中0-25以A-Z表示,26-51以a-z表示,52-61以0-9表示,62对应+,63对应/

对此,我们可以自己写个函数来实现上述几个取id值的功能,将相应部分转换成10进制的数字即可

create or replace function convert64to10(str in varchar2)
return number
as
result number:=0;
tmp char(1);
begin
for i in 1..length(str) loop
tmp:=substr(str,i,1);
result:=result+power(64,(length(str)-i))*(ascii(tmp)-
case when tmp between 'A' and 'Z' then 65
when tmp between 'a' and 'z' then 71
when tmp between '0' and '9' then -4
when tmp = '+' then -19
when tmp = '/' then -16
else 1/0 end);
end loop;
return result;
exception
when others then
return 0;
end;
/

ok,用这个函数从rowid中取4个部分的值试试

select id,
convert64to10(substr(rowid,1,6)) object_id,
convert64to10(substr(rowid,7,3)) file_id,
convert64to10(substr(rowid,10,6)) block_id,
convert64to10(substr(rowid,16,3)) row_no,
rowid rid
from a;

ID OBJECT_ID FILE_ID BLOCK_ID ROW_NO RID
---------- ---------- ---------- ---------- ---------- ------------------
2 53057 4 110653 0 AAAM9BAAEAAAbA9AAA
3 53057 4 110653 1 AAAM9BAAEAAAbA9AAB

是否与用dbms_rowid包取得的一致?

你可能感兴趣的:(rowid)