標籤:rowid
rowid記錄資料的物理位置,通過rowid可以知道資料存放在那個資料檔案的第幾個塊第幾行。
---------------------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~25a~z : 26~510~9 : 52-61+ : 62 / : 63-------------------------------
例:AAE轉為十進位,方法如下:A = 0E = 4AAE = 0*64^2 + 0*64^1 + 4*64^0 = 4 轉換過程:把AAE解析成64進位的資料,然後每個位元*64的N次方,再相加後的值就是10進位。
轉換原理已清楚,下面使用代碼來解析rowid資訊,不過代碼寫得太……
----------------------------------------------------------AAAY50 AAG AAAACL AAA--1,6 7,3 10,6 16,3--處理rowidcreate or replace procedure v_oprowid(v_rowid in varchar2)asv_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----------------------------------------------------------------
執行方法:
SQL> set serveroutput onSQL> exec v_oprowid(‘AAAY50AAGAAAACLAAB‘)object_data_id:102004relative_fno:6blockid:139xingid:1PL/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;
本文出自 “儘管錯,讓我錯到死!” 部落格,請務必保留此出處http://hxw168.blog.51cto.com/8718136/1556624
【oracle】rowid解讀