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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12932950/viewspace-620003/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JavaScript 進位制轉換(2進位制、8進位制、10進位制、16進位制之間的轉換)JavaScript
- 進位制之間的轉換之“十六進位制 轉 十進位制 轉 二進位制 方案”
- 2進位制_8進位制_16進位制之間快速轉換的技巧.txt
- 二進位制,八進位制,十進位制,十六進位制之間的轉換
- C# 2進位制、8進位制、10進位制、16進位制...各種進位制間的輕鬆轉換C#
- 大話二進位制,八進位制,十進位制,十六進位制之間的轉換
- 【進位制轉換】十進位制與十六進位制相互轉換方法
- JAVA 二進位制,八進位制,十六進位制,十進位制間進行相互轉換Java
- Python 進位制互相轉換(二進位制、十進位制和十六進位制)Python
- Qt進位制轉換(十進位制轉十六進位制)QT
- 二進位制,八進位制,十進位制,十六進位制的相互轉換
- Oracle二進位制與十進位制轉換Oracle
- shell 中轉換16進位制10進位制
- oracle_16進位制與10進位制轉換小示例Oracle
- java中二進位制、八進位制、十進位制、十六進位制的轉換Java
- lua之m進位制轉換為n進位制-任意進位制轉換演算法演算法
- JavaScript中的多種進位制與進位制轉換JavaScript
- 10進位制 VS 2進位制
- 十進位制與二進位制互相轉換指南
- 進位制與二進位制及相關轉換
- 【進位制轉換】二進位制、十六進位制、十進位制、八進位制對應關係
- python進位制轉換(二進位制、十進位制和十六進位制)及注意事項Python
- 口算 16 進位制轉換 10 進位制,但只適合兩位的 16 進位制
- 計算機基礎進位制轉換(二進位制、八進位制、十進位制、十六進位制)計算機
- 10進位制和16進位制互轉的例子
- 十六進位制轉換為八進位制
- 十六進位制轉換為十進位制
- Oracle中十進位制與十六進位制轉換程式Oracle
- 計算機求解10進位制轉換任意進位制計算機
- js二進位制和十進位制轉換程式碼JS
- Oracle中的二進位制、八進位制、十進位制、十六進位制相互轉換函式Oracle函式
- 第42篇 字元與進位制之間的轉換字元
- 【轉帖】Oracle中的二進位制、八進位制、十進位制、十六進位制相互轉換函式Oracle函式
- Python不同進位制之間的轉換Python
- 進位制轉換
- js 62進位制和10進位制相互轉換程式碼例項JS
- 二進位制、十進位制與十六進位制相互轉化
- 二進位制轉十進位制快速轉換方法