DBMS_ROWID包
DBMS_ROWID包允许我们使用PL/SQL程序或SQL语句创建rowids和获取rowid的信息。例如可以通过其找到数据对象编号,数据文件编号,包含数据行的数据块编号及数据块中的数据行。该包从Oracle 8.X开始可用。
DBMS_ROWID的几个子函数程序:如下:
1、ROWID_BLOCK_NUMBER函数(该函数返回输入ROWID的数据块编号)
语法:
DBMS_ROWID.ROWID_BLOCK_NUMBER(
row_id IN ROWID,
ts_type_in IN VARCHAR2 DEFAULT 'SMAILLFILE')
返回值是number类型。
参数:
row_id:被转换的rowid。
ts_type_in:数据行所在表空间类型,默认是SMALLFILE,即小数据文件表空间。
SQL> select dbms_rowid.rowid_block_number(rowid,'smallfile') block_id from emp;
BLOCK_ID
----------
151
151
151
151
151
151
151
151
151
151
151
BLOCK_ID
----------
151
151
13 rows selected.
2.ROWID_RELATIVE_FNO函数(该函数根据输入的ROWID值,返回其所在数据文件编号)
语法:
DBMS_ROWID.ROWID_RELATIVE_FNO (
rowid_id IN ROWID,
ts_type_in IN VARCHAR2 DEFAULT 'SMALLFILE')
RETURN NUMBER;
举例:
SQL> select dbms_rowid.rowid_relative_fno(ROWID) FILE# from emp;
FILE#
----------
4
4
4
4
4
4
4
4
4
4
4
FILE#
----------
4
4
13 rows selected.
3.ROWID_ROW_NUMBER函数(该函数根据输入的ROWID提取出行(row)号)
语法:
DBMS_ROWID.ROWID_ROW_NUMBER (row_id IN ROWID)
RETURN NUMBER;
举例:
SQL> select dbms_rowid.rowid_row_number(ROWID) ROW_NUM from emp;
ROW_NUM
----------
1
2
3
4
5
6
7
8
9
10
11
ROW_NUM
----------
12
13
13 rows selected.
DBMS_ROWID定位数据行物理存储位置实例:
对于Oracle中的堆表,我们可以通过oracle内置的ROWID伪列得到对应行记录所在的ROWID的值(注意,这个ROWID只是一个伪列,实际的块中并不存在该列)。然后我们可以通过DBMS_ROWID包中的相关方法来通过ROWID伪列来定位对应数据行的实际物理存储物理地址。
dbms_rowid.rowid_relative_fno:定位该数据行所在的数据文件
dbms_rowid.rowid_block_number:定位该数据行在数据文件的第多少个块
dbms_rowid.rowid_row_number:定位该数据行在数据块的第多少行
下面举例进行查看:
SQL> desc emp
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
SQL>
SQL> col location for a20
SQL> select empno,rowid,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid)||'_'||dbms_rowid.rowid_row_number(rowid) location from emp;
EMPNO ROWID LOCATION
---------- ------------------ --------------------
7499 AAAVREAAEAAAACXAAB 4_151_1
7521 AAAVREAAEAAAACXAAC 4_151_2
7566 AAAVREAAEAAAACXAAD 4_151_3
7654 AAAVREAAEAAAACXAAE 4_151_4
7698 AAAVREAAEAAAACXAAF 4_151_5
7782 AAAVREAAEAAAACXAAG 4_151_6
7788 AAAVREAAEAAAACXAAH 4_151_7
7839 AAAVREAAEAAAACXAAI 4_151_8
7844 AAAVREAAEAAAACXAAJ 4_151_9
7876 AAAVREAAEAAAACXAAK 4_151_10
7900 AAAVREAAEAAAACXAAL 4_151_11
EMPNO ROWID LOCATION
---------- ------------------ --------------------
7902 AAAVREAAEAAAACXAAM 4_151_12
7934 AAAVREAAEAAAACXAAN 4_151_13
13 rows selected.
拿第一行数据进行说明该行的ROWID伪列的值为 AAAVREAAEAAAACXAAB,可以通过ROWID包通过这个ROWID伪列转换出来的值为4_151_1,代表该行在数据文件4的第151个数据块的第1行。
=================补充====================
语法:
DBMS_ROWID.ROWID_CREATE (
rowid_type IN NUMBER,
object_number IN NUMBER,
relative_fno IN NUMBER,
block_number IN NUMBER,
row_number IN NUMBER)
参数:
rowid_type:rowid类型(restricted或者extended)。设置rowid_type为0时,代表restricted
ROWID(此时,将忽略参数object_number),设置rowid_type为1时,代表extended ROWID。
object_number:数据对象编号(仅restricted类型rowid可用)。
relative_fno:所在数据文件编号。
block_number:该数据文件中的数据块编号。
row_number:在该块中的行编号。
举例:
创建restricted ROWID
SQL> select dbms_rowid.rowid_create(0,9999,12,1000,13) from dual;
DBMS_ROWID.ROWID_C
------------------
000003E8.000D.000C
创建extended ROWID
SQL> select dbms_rowid.rowid_create(1,9999,12,1000,13) from dual;
DBMS_ROWID.ROWID_C
------------------
AAACcPAAMAAAAPoAAN
2.ROWID_INFO过程(该过程返回一个ROWID的相关信息,包括类型和ROWID的一些其他部分,注意:这时一个存储过程,不能在SQL语句中使用)
语法:
DBMS_ROWID.ROWID_INFO (
rowid_in IN ROWID, --输入参数
ts_type_in IN VARCHAR2 DEFAULT 'SMALLFILE', --输入参数
rowid_type OUT NUMBER, --out代表输出参数
object_number OUT NUMBER,
relative_fno OUT NUMBER,
block_number OUT NUMBER,
row_number OUT NUMBER);
参数:
rowid_in:ROWID to be interpreted. This determines if the ROWID is a restricted (0) or extended (1) ROWID.
ts_type_in:The type of the tablespace (bigfile/smallfile) to which the row belongs.
rowid_type:Returns type (restricted/extended).
object_number:Returns data object number (rowid_object_undefined for restricted).
relative_fno:Returns relative file number.
block_number:Returns block number in this file.
row_number:Returns row number in this block.
举例:
SQL> set serverout on set serverout on
declare
my_rowid rowid;
rowid_type number;
object_number number;
relative_fno number;
block_number number;
row_number number;
begin
my_rowid :=dbms_rowid.rowid_create(1, 6877,1,23722,0);
dbms_rowid.rowid_info(my_rowid, rowid_type, object_number,
relative_fno, block_number, row_number);
dbms_output.put_line('ROWID: ' || my_rowid);
dbms_output.put_line('Object#: ' || object_number);
dbms_output.put_line('RelFile#: ' || relative_fno);
dbms_output.put_line('Block#: ' || block_number);
dbms_output.put_line('Row#: ' || row_number);
end;
/
ROWID: AAABrdAABAAAFyqAAA
Object#: 6877
RelFile#: 1
Block#: 23722
Row#: 0
PL/SQL procedure successfully completed.
3.ROWID_OBJECT函数(该函数返回扩展ROWID的数据对象编号,如果输入的ROWID类型为restricted,则该函数返回值为0)
语法:
DBMS_ROWID.ROWID_OBJECT (rowid_id IN ROWID)
举例:
SQL> select dbms_rowid.rowid_object(ROWID) from T1 where rownum<5;
DBMS_ROWID.ROWID_OBJECT(ROWID)
------------------------------
88767
88767
88767
88767
4.ROWID_TO_ABSOLUTE_FNO函数(从输入的ROWID中提取出其所在完全文件号)
语法:
DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO (
row_id IN ROWID,
schema_name IN VARCHAR2,
object_name IN VARCHAR2)
RETURN NUMBER;
举例:
SQL> select dbms_rowid.rowid_to_absolute_fno(rowid,'SCOTT','DEPT') FROM DEPT;
DBMS_ROWID.ROWID_TO_ABSOLUTE_FNO(ROWID,'SCOTT','DEPT')
------------------------------------------------------
4
4
4
4
5.ROWID_TYPE函数(返回ROWID的类型,返回0代表restricted ROWID;返回1代表extended ROWID)
语法:
DBMS_ROWID.ROWID_TYPE (
rowid_id IN ROWID)
RETURN NUMBER;
举例:
SQL> select dbms_rowid.rowid_type(rowid) from dept;
DBMS_ROWID.ROWID_TYPE(ROWID)
----------------------------
1
1
1
1