ROWID是访问数据库中表的物理地址信息,Oracle提供了ROWID伪列,可以通过ROWID直接访问表中的数据。
ROWNUM固化外部表结果集存在问题:https://yangtingkun.net/?p=38
ROWNUM固化外部表结果集存在问题(二):https://yangtingkun.net/?p=103
在测试外部表时,意外发现,外部表同样存在ROWID伪列:
SQL> CREATE directory d_alert AS 'D:\ORACLE\PRODUCT\ADMIN\YTK102\BDUMP'; 目录已创建。 SQL> CREATE TABLE t_alert 2 (text varchar2(1000) 3 ) 4 organization external 5 (TYPE oracle_loader 6 DEFAULT directory d_alert 7 access parameters 8 (records delimited BY newline 9 FIELDS (text (1:255) CHAR)) 10 location ('alert_ytk102.log')); 表已创建。 SQL> SELECT * FROM t_alert WHERE rownum < 10; TEXT ----------------------------------------------------------------------------- Dump file d:\oracle\product\admin\ytk102\bdump\alert_ytk102.log Sat DEC 25 15:55:43 2010 ORACLE V10.2.0.5.0 - Production vsnsta=0 vsnsql=14 vsnxtr=3 Windows NT Version V6.1 CPU : 4 - TYPE 586, 2 Physical Cores Process Affinity : 0x00000000 Memory (Avail/Total): Ph:1594M/2995M, Ph+PgF:4318M/5989M, VA:1911M/2047M Sat DEC 25 15:55:43 2010 已选择9行。 SQL> SELECT ROWID FROM T_ALERT WHERE ROWNUM < 10; ROWID ----------------------- (AADRCQAAAAAAAAAAAAAAAA (AADRCQAAAAAAAAAAAAAAQQ (AADRCQAAAAAAAAAAAAAAXA (AADRCQAAAAAAAAAAAAAAhg (AADRCQAAAAAAAAAAAAAAmg (AADRCQAAAAAAAAAAAAAAtA (AADRCQAAAAAAAAAAAAAA6g (AADRCQAAAAAAAAAAAAABDA (AADRCQAAAAAAAAAAAAABVg 已选择9行。 |
显然外部表的ROWID和普通表的ROWID有着明显的区别,其长度并非18位,换句话说,外部表的ROWID并非是OBJECT_ID + RELATIVE FILE_ID + BLOCK_NUMBER + ROW_NUMBER格式。
既然外部表的ROWID并不代表一个物理地址,因此一般也没有机会去使用这个ROWID,不过有时确实需要使用一个ROWID来解决真实的问题:
SQL> WITH A AS (SELECT ROW_NUMBER() OVER(ORDER BY ROWID) RN, TEXT FROM T_ALERT) 2 SELECT * FROM A B 3 WHERE B.RN >= (SELECT MIN(C.RN) FROM A C WHERE TEXT = 'Mon Sep 19 07:18:21 2011'); RN TEXT ---------- -------------------------------------------------------------------------------- 5739 Mon Sep 19 07:18:21 2011 5740 Successfully onlined Undo Tablespace 1. 5741 Mon Sep 19 07:18:21 2011 5742 SMON: enabling tx recovery 5743 Mon Sep 19 07:18:21 2011 5744 DATABASE Characterset IS ZHS16GBK 5745 Opening WITH internal Resource Manager plan 5746 replication_dependency_tracking turned off (no async multimaster replication found) 5747 Starting background process QMNC 5748 QMNC started WITH pid=17, OS id=5412 5749 Mon Sep 19 07:18:29 2011 5750 Completed: ALTER DATABASE OPEN 已选择12行。 |
由于ROW_NUMBER分析函数需要一个ORDER BY排序字段,而在这个例子中,依赖于外部表的读取顺序,而并没有任何一个列能标识这个顺序,而ROWID变成了唯一的选项,恰好Oracle在实现外部表的伪列的时候,ROWID的大小是根据外部表数据读取顺序递增的,因此这里使用ROWID作为ORDER BY的排序列,可以满足查询的要求,这也是外部表ROWID有意义的应用之一。
Pingback: ORA-600(qknltAllocate_10)错误 | yangtingkun