oracle的rowid转成数字,rowid与10进制和2进制之间的转换

通过对rowid的各种转换的实现,更进一步的了解了它的组成,下面是一段rowid在10进制和2进制之间的转换过程,只显示了部分内容(全部内容见附件):

这里有些背景知识再罗嗦一下。我们知道,rowid是oracle中标识一条记录的唯一标识,是一个64进制的数值。

总共有18位组成(9i及9i以后,8i的是16位),也就是6(object_id) + 3(relative_fno ) + 6(block_number) + 3(row_number)这些组成。

因此,我将rowid按照以上区间划分,分别取到对应的编号,然后转成4个10进制数值。由于rowid是由26个大写英文+26个小写英文+10个数字++/组成,所以就有了g_64这个变量值,64转10进制的原理就是从rowid中取到一个字符到g_64中去查找,找到对应的位置即是该值对应加权值。

如现在有rowid的object_id对应的值:AAAAAZ。可以知道A对应的位置是0(从0开始计数),Z对应的是25,所以转成10进制为:

0*64^5 + 0*64^4 + 0*64^3 +  0*64^2 +  0*64^1 +  25*64^0 = 25。即object_id为25。依次转换成4个10进制数后,再将这四个值转换成2进制。比如25,转成二进制就变为11001。

根据rowid二进制的组成规则,是32+10+22+16。所以,还需要将11001“加长”为32位的,于是就有:

00000000000000000000000000011001了。

其他的依次类推。

从这里我们也可以知道,oracle可支持的最大文件数有2^10=1024。即每个表空间可支持1024个数据文件。而每个数据文件则有2^22个block组成。假设一个block为8k,则一个表空间最大可以为:8k*2^22(32T)的容量。

以下是具体进制间的转换过程:

.................

g_64  varchar2(64) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

function x64_to_dec(x64 varchar2) return varchar2 as

type t_chrs is table of varchar2(10) index by pls_integer;

type t_nums is table of number(10);

v_chrs t_chrs;

v_fmt  t_nums := t_nums(32,10,22,16);--total:80 二进制划分区间

v_r64p t_nums := t_nums(6, 3, 6, 3); --total:18 64进制划分区间(rowid)

v_ren  t_nums := t_nums(0, 0, 0, 0);

v_bins varchar2(80) := '';

v_trnx varchar2(1000) := '';

function spart(str varchar2, n int) return varchar2 as

v_begin integer := 0;

begin

for i in 1 .. n - 1 loop

v_begin := v_begin + v_r64p(i);

end loop;

return substr(str, v_begin + 1, v_r64p(n));

end spart;

begin

--获取rowid的分段列表6/3/6/3

for j in v_r64p.first .. v_r64p.last loop

v_chrs(j) := spart(x64, j);

end loop;

--转换为10进制

for i in 1 .. v_chrs.count loop

for j in 1 .. length(v_chrs(i)) loop

v_ren(i) := v_ren(i) + power(64, length(v_chrs(i)) - j) * (instr(g_64, substr(v_chrs(i), j, 1)) - 1);

end loop;

end loop;

--将数值转换为二进制,并按照32/10/12/16进行lpad,再全部拼接

for k in 1 .. v_ren.count loop

v_bins := v_bins || lpad(dec_to_bin(v_ren(k)), v_fmt(k), '0');

end loop;

--将拼接的二进制串划分为每个8bit、共10个的二进制串

--此结果即为dump(rowid)的结果

for i in 0 .. length(v_bins)/8 - 1 loop

v_trnx := v_trnx || ',' || bin_to_dec(substr(v_bins, i*8 + 1, 8));

end loop;

v_trnx := '/OFBR[' || v_ren(1) || ',' || v_ren(2) || ',' || v_ren(3) || ',' || v_ren(4) || ']/DUMP[' || v_trnx || ']';

return v_trnx;

end x64_to_dec;

........

测试结果:

SQL> select rowid, ntx.x64_to_dec(rowid), dump(rowid),

2         --length(ntx.x64_to_dec(rowid)) len,

3         dbms_rowid.rowid_object(rowid) object_id,

4         dbms_rowid.rowid_relative_fno(rowid) fno,

5         dbms_rowid.rowid_block_number(rowid) blkno,

6         dbms_rowid.rowid_row_number(rowid) rowno

7    from t

8   where rownum <= 1 ;

ROWID              NTX.X64_TO_DEC(ROWID)                                                            DUMP(ROWID)                                                                       OBJECT_ID        FNO      BLKNO      ROWNO

------------------ -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ---------- ---------- ---------- ----------

AAAO0gAAYAAAA8NAAA /OFBR[60704,24,3853,0]/DUMP[,0,0,237,32,6,0,15,13,0,0]                           Typ=69 Len=10: 0,0,237,32,6,0,15,13,0,0                                               60704         24       3853          0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值