设为首页 加入收藏

TOP

使用rowid和rownum获取记录时要注意的问题(一)
2015-07-24 10:44:57 来源: 作者: 【 】 浏览:1
Tags:使用 rowid rownum 获取 记录 时要 注意 问题
我们知道,rowid和rownum在Oracle中都是可以被当做伪劣使用的,主要用来定位表中特定的记录,但它们是有区别的,rowid是和行记录的物理地址对应的,而rownum则不是,是通过返回的记录集来判断首条记录,即rownum=1的记录,然后再去fetch之后的记录,rownum=2、rownum=3……,以此类推。下面来看实验:
SQL> conn zlm/zlm
Connected. SQL> create table test1 as select object_id,object_name from dba_objects where rownum<11;
Table created.
注意,创建表的时候,也用到了rownum<11这个伪列上的where条件,获取到10条记录插入到test1表。
SQL> set lin 130 pages 130 SQL> col object_name for a30 SQL> select * from test1;
OBJECT_ID OBJECT_NAME ---------- ------------------------------ 20 ICOL$ 44 I_USER1 28 CON$ 15 UNDO$ 29 C_COBJ# 3 I_OBJ# 25 PROXY_ROLE_DATA$ 39 I_IND1 51 I_CDEF2 26 I_PROXY_ROLE_DATA$_1
10 rows selected.

用*来表示全部列,此时并不会显示出rowid,rownum这2个伪列,这也就是“伪列”这个名词的由来,是假的,fake的,我们可以使用它,但并不作为数据存储在表中
SQL> select rowid,rownum,object_id,object_name from test1;
ROWID ROWNUM OBJECT_ID OBJECT_NAME ------------------ ---------- ---------- ------------------------------ AAAM+rAAGAAAACUAAA 1 20 ICOL$ AAAM+rAAGAAAACUAAB 2 44 I_USER1 AAAM+rAAGAAAACUAAC 3 28 CON$ AAAM+rAAGAAAACUAAD 4 15 UNDO$ AAAM+rAAGAAAACUAAE 5 29 C_COBJ# AAAM+rAAGAAAACUAAF 6 3 I_OBJ# AAAM+rAAGAAAACUAAG 7 25 PROXY_ROLE_DATA$ AAAM+rAAGAAAACUAAH 8 39 I_IND1 AAAM+rAAGAAAACUAAI 9 51 I_CDEF2 AAAM+rAAGAAAACUAAJ 10 26 I_PROXY_ROLE_DATA$_1
10 rows selected.
把列名全部显示指定,可以看到,rowid和rownum这两列的内容也都显示了。那我们能不能用rowid列来作为查找条件呢?当然是可以的,但前提是你要知道rowid值是怎么分布的
SQL> select rowid,object_id,object_name from test1 where rowid ROWID OBJECT_ID OBJECT_NAME ------------------ ---------- ------------------------------ AAAM+rAAGAAAACUAAA 20 ICOL$ AAAM+rAAGAAAACUAAB 44 I_USER1 AAAM+rAAGAAAACUAAC 28 CON$ AAAM+rAAGAAAACUAAD 15 UNDO$ AAAM+rAAGAAAACUAAE 29 C_COBJ# AAAM+rAAGAAAACUAAF 3 I_OBJ# AAAM+rAAGAAAACUAAG 25 PROXY_ROLE_DATA$ AAAM+rAAGAAAACUAAH 39 I_IND1 AAAM+rAAGAAAACUAAI 51 I_CDEF2 AAAM+rAAGAAAACUAAJ 26 I_PROXY_ROLE_DATA$_1
10 rows selected.
为什么条件是 这里来说明一下rowid中这些字母表示的含义:
在Oracle 8以下,rowid(也叫受限rowid)为:FFFF.BBBBBBBB.RRRR,占用6个字节(10bit file#+22bit+16bit),但是,为了扩充的需要,如数据文件的扩充,现在的rowid改为:OOOOOOFFFBBBBBBRRR,占用10个字节(32bit+10bit rfile#+22bit+16bit)。其中,O是Object号,F是File号,B是Block号,R是Row号。由于rowid的组成从file#变成了rfile#,所以数据文件数的限制也从整个库不能超过1023个变成了每个表空间不能超过1023个数据文件。这里的object_id,是与段物理存储位置相关的一个信息,因为一个段对象只可能在一个表空间上,object_id能唯一确认ts#,而object_id + rfile#就能最终定位到该rowid在哪个确定的物理数据文件上

因此,这里的AAG就表示这是第6个数据文件,要注意的是,AAA从0开始计数,行号也是如此。因此,AAA-AAJ就表示是test1表中的1-10行记录(0->9)

SQL> col name for a45 SQL> select file#,name from v$datafile;
FILE# NAME ---------- --------------------------------------------- 1 /u01/app/oracle/oradata/ora10g/system01.dbf 2 /u01/app/oracle/oradata/ora10g/undotbs01.dbf 3 /u01/app/oracle/oradata/ora10g/sysaux01.dbf 4 /u01/app/oracle/oradata/ora10g/users01.dbf 5 /u01/app/oracle/oradata/ora10g/example01.dbf 6 /u01/app/oracle/oradata/ora10g/zlm01.dbf
zlm用户默认的表空间就是zlm,其对应的数据文件就是zlm01.dbf,可以看到,file#为6而并不是7
我们还可以用Oracle提供的dbms.rowid包来根据rowid的值来获取object_id#,rfile#,block#,row#这些具体的值:
SQL> select dbms_rowid.rowid_object('AAAM+rAAGAAAACUAAJ') object_id#,dbms_rowid.rowid_relative_fno('AAAM+rAAGAAAACUAAJ') rfile#,dbms_rowid.rowid_block_number('AAAM+rAAGAAAACUAAJ') block#,dbms_rowid.rowid_row_number('AAAM+rAAGAAAACUAAJ') row# from dual;
OBJECT_ID# RFILE# BLOCK# ROW# --------------- ---------- ---------- ---------- 53163 6 148 9
test1表中第10行记录就是第53163个对象、第6号文件、第148个块
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇改变Eclipse中代码字体大小 下一篇oracle数组

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)
·[ Linux运维学习 ] (2025-12-26 02:52:27)
·HTTPS 详解一:附带 (2025-12-26 02:20:37)
·TCP/IP协议到底在讲 (2025-12-26 02:20:34)