rowid記錄數據的物理位置,經過rowid能夠知道數據存放在那個數據文件的第幾個塊第幾行。sql
--------------------- extended rowid format ---------------------------------------------------- AAAEoF AAE AAAACL AAA ---------------------------------------------------- data object relative file block row number number number number ---------------------- 第一部分:數據段id select * from dba_objects 第二部分:文件的相對編號 dba_data_files 第三部分:塊編號 第四部分:行編號,這個塊上的第幾行 rowid:記錄這條數據的物理位置 rowid使用64進制,定義以下: ----------------------------- A~Z : 0~25 a~z : 26~51 0~9 : 52-61 + : 62 / : 63 -------------------------------
例:AAE轉爲十進制,方法以下: A = 0 E = 4 AAE = 0*64^2 + 0*64^1 + 4*64^0 = 4 轉換過程:把AAE解析成64進制的數據,而後每一個位數*64的N次方,再相加後的值就是10進制。
轉換原理已清楚,下面使用代碼來解析rowid信息,不過代碼寫得太……oracle
-------------------------------------------------------- --AAAY50 AAG AAAACL AAA --1,6 7,3 10,6 16,3 --處理rowid create or replace procedure v_oprowid(v_rowid in varchar2) as v_dataid varchar2(6); v_rfileid varchar2(3); v_blockid varchar2(6); v_xingid varchar2(3); v_all varchar(32); v_chk number; v_temp number; v_temp64 number default 0; begin select substr(v_rowid,1,6),substr(v_rowid,7,3),substr(v_rowid,10,6), substr(v_rowid,16,3) into v_dataid,v_rfileid,v_blockid,v_xingid from dual; --dbms_output.put_line('objecct_id:'||v_dataid||',rfileid:' --||v_rfileid||',blockid:'||v_blockid||',xingid:'||v_xingid); for i in 1..6 loop v_temp:=ascii(substr(v_dataid,i,1)); v_chk:= v_temp-65; if v_chk>=0 and v_chk <= 25 then v_temp64 :=v_temp64+v_chk*power(64,6-i); end if; if v_chk < 0 and v_chk>=-17 then v_temp64 :=v_temp64+(v_chk+69)*power(64,6-i); end if; if v_chk >=32 and v_chk<=57 then v_temp64 :=v_temp64+(v_chk-6)*power(64,6-i); end if; if v_chk=-22 then v_temp64 :=v_temp64+62*power(64,6-i); end if; if v_chk=-18 then v_temp64 :=v_temp64+63*power(64,6-i); end if; end loop; dbms_output.put_line('object_data_id:'||v_temp64); --relative_fno v_temp64:=0; for i in 1..3 loop v_temp:=ascii(substr(v_rfileid,i,1)); v_chk:= v_temp-65; if v_chk>=0 and v_chk <= 25 then v_temp64 :=v_temp64+v_chk*power(64,3-i); end if; if v_chk < 0 and v_chk>=-17 then v_temp64 :=v_temp64+(v_chk+69)*power(64,3-i); end if; if v_chk >=32 and v_chk<=57 then v_temp64 :=v_temp64+(v_chk-6)*power(64,3-i); end if; if v_chk=-22 then v_temp64 :=v_temp64+62*power(64,3-i); end if; if v_chk=-18 then v_temp64 :=v_temp64+63*power(64,3-i); end if; end loop; dbms_output.put_line('relative_fno:'||v_temp64); -- v_temp64:=0; for i in 1..6 loop v_temp:=ascii(substr(v_blockid,i,1)); v_chk:= v_temp-65; if v_chk>=0 and v_chk <= 25 then v_temp64 :=v_temp64+v_chk*power(64,6-i); end if; if v_chk < 0 and v_chk>=-17 then v_temp64 :=v_temp64+(v_chk+69)*power(64,6-i); end if; if v_chk >=32 and v_chk<=57 then v_temp64 :=v_temp64+(v_chk-6)*power(64,6-i); end if; if v_chk=-22 then v_temp64 :=v_temp64+62*power(64,6-i); end if; if v_chk=-18 then v_temp64 :=v_temp64+63*power(64,6-i); end if; end loop; dbms_output.put_line('blockid:'||v_temp64); --- v_temp64:=0; for i in 1..3 loop v_temp:=ascii(substr(v_xingid,i,1)); v_chk:= v_temp-65; if v_chk>=0 and v_chk <= 25 then v_temp64 :=v_temp64+v_chk*power(64,3-i); end if; if v_chk < 0 and v_chk>=-17 then v_temp64 :=v_temp64+(v_chk+69)*power(64,3-i); end if; if v_chk >=32 and v_chk<=57 then v_temp64 :=v_temp64+(v_chk-6)*power(64,3-i); end if; if v_chk=-22 then v_temp64 :=v_temp64+62*power(64,3-i); end if; if v_chk=-18 then v_temp64 :=v_temp64+63*power(64,3-i); end if; end loop; dbms_output.put_line('xingid:'||v_temp64); end; --procedure end ----------------------------------------------------------------
執行方法:ide
SQL> set serveroutput on SQL> exec v_oprowid('AAAY50AAGAAAACLAAB') object_data_id:102004 relative_fno:6 blockid:139 xingid:1 PL/SQL 過程已成功完成。 SQL>
oracle提供dbms_rowid包中的函數能夠讀取rowid解析成可讀信息,語句以下:函數
select dbms_rowid.rowid_object(rowid), dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid), dbms_rowid.rowid_row_number(rowid),rowid from wen.t;