【oracle】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~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信息,不过代码写得太……

--------------------------------------------------------
--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
----------------------------------------------------------------

执行方法:

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;
时间: 2024-08-10 22:57:53

【oracle】rowid解读的相关文章

Oracle ROWID详解

1.ROWID定义 ROWID:数据库中行的全局唯一地址 对于数据中的每一行,rowid伪列返回行的地址.rowid值主要包含以下信息: 对象的数据对象编号 该行所在的数据文件中的数据块 该行中数据块的位置(第一行是0) 数据行所在的数据文件(第一个文件是1).该文件编号是相对于表空间. 通常来说,一个rowid值唯一标识数据中的一行.然而,存储在同一聚簇中不同的表可以有相同的rowid. 2.扩展ROWID 从Oracle 8i开始使用扩展rowid标识行物理地址 扩展rowid使用base6

Oracle ROWID具体解释

1.ROWID定义 ROWID:数据库中行的全局唯一地址 对于数据中的每一行,rowid伪列返回行的地址.rowid值主要包括下面信息: 对象的数据对象编号 该行所在的数据文件里的数据块 该行中数据块的位置(第一行是0) 数据行所在的数据文件(第一个文件是1).该文件编号是相对于表空间. 通常来说.一个rowid值唯一标识数据中的一行.然而,存储在同一聚簇中不同的表能够有同样的rowid. 2.扩展ROWID 从Oracle 8i開始使用扩展rowid标识行物理地址 扩展rowid使用base6

oracle rowid 使用

ROWID是数据的详细地址,通过rowid,oracle可以快速的定位某行具体的数据的位置. ROWID可以分为物理rowid和逻辑rowid两种.普通的堆表中的rowid是物理rowid,索引组织表(IOT)的rowid是逻辑rowid.oracle提供了一种urowid的数据类型,同时支持物理和逻辑rowid.本文主要关注物理rowid 物理rowid又分为扩展rowid(extended rowid)和限制rowid(restricted rowid)两种格式.限制rowid主要是orac

ORACLE rowid,file# 和 rfile#

rowid简介 rowid就是唯一标志记录物理位置的一个id,在oracle 8版本以前,rowid由file#+block#+row#组成,占用6个bytes的空间,10 bit 的 file# ,22bit 的 block# ,16 bit 的 row#. 从oracle 8开始rowid变成了extend rowid,由data_object_id#+rfile#+block#+row#组成,占用10个bytes的空间, 32bit的 data_object_id#,10 bit 的 rf

Oracle rowid

一.Rowid rowid是伪列(pseudocolumn),伪劣的意思是实际上这一列本身在数据字典中并不存在,在查询结果输出时它被构造出来的. rowid并不会真正存在于表的data block中,但是他会存在于index当中,用来通过rowid来寻找表中的行数据 二.Rowid的结构 限制rowid:用于早期Oracle版本(Oracle 8 以前),rowid由(10 bit)file#+(22 bit)block#+(16 bit)row#组成,占用6个bytes的空间 注:file#为

Oracle ROWID与UROWID

Oracle使用rowid数据类型存储行地址,rowid可以分成两种,分别适于不同的对像 Physical rowids:存储ordinary table,clustered table,table partition and subpartition,indexe,index partition and subpartition Logical rowids : 存储IOT的行地址 另一种rowid类型叫universal rowed(UROWID),支持上述physical rowid和lo

ORACLE rowid切分大表

通过如下sql获取rowid切分范围 SELECT rownum || ', ' || ' rowid between ' || chr(39) || dbms_rowid.rowid_create(1, DOI, lo_fno, lo_block, 0) || chr(39) || ' and ' || chr(39) || dbms_rowid.rowid_create(1, DOI, hi_fno, hi_block, 1000000) || chr(39) data FROM (SELE

【转载】oracle索引详解2

原文URL:http://justplayoop1.iteye.com/blog/1259562 一. 索引介绍 1.1  索引的创建 语法 : CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> ON <schema>.<table_name> (<column_name> | <expression> ASC | DESC,                <column_na

Oracle corrupt block(坏块) 详解

转自:http://blog.csdn.net/tianlesoftware/article/details/5024966 一. 坏块说明 1.1 相关链接 在看坏块之前,先看几个相关的链接,在后面的说明中,会用到链接中的一些内容. ORA-600 各个参数含义说明 http://blog.csdn.net/tianlesoftware/article/details/6645809 Oracle 不同故障的恢复方案 http://blog.csdn.net/tianlesoftware/ar