大家都知道rowid表示的是记录的物理存储位置,那么在一个join view里面rowid又是从哪里来的呢?
SQL 10G>desc t1
Name Null? Type
----------------------------------------- -------- ----------------------------
A NOT NULL NUMBER
SQL 10G>desc t2
Name Null? Type
----------------------------------------- -------- ----------------------------
A NOT NULL NUMBER
SQL 10G>create or replace view v_t as select t1.a from t1,t2 where t1.a=t2.a;
View created.
SQL 10G>select rowid,a from t1;
ROWID A
------------------ ----------
AAAOVgAAEAAAAcOAAA 1
SQL 10G>select rowid,a from t2;
ROWID A
------------------ ----------
AAAOVhAAEAAAAcWAAA 1
SQL 10G>select rowid,a from v_t;
ROWID A
------------------ ----------
AAAOVhAAEAAAAcWAAA 1
SQL 10G>set autotrace trace;
SQL 10G>/
Execution Plan
----------------------------------------------------------
Plan hash value: 3514408644
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 1 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 1 | 6 | 1 (0)| 00:00:01 |
| 2 | INDEX FULL SCAN | PK_T1 | 1 | 3 | 1 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN| PK_T2 | 1 | 3 | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------
可以看到v_t的rowid是和t2一样的,我们来重新定义一下view,互换一下t1,t2的位置
SQL 10G>create or replace view v_t as select t1.a from t2,t1 where t1.a=t2.a;
View created.
SQL 10G>select rowid,a from v_t;
Execution Plan
----------------------------------------------------------
Plan hash value: 3071778297
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 1 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 1 | 6 | 1 (0)| 00:00:01 |
| 2 | INDEX FULL SCAN | PK_T2 | 1 | 3 | 1 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN| PK_T1 | 1 | 3 | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------
SQL 10G>/
ROWID A
------------------ ----------
AAAOVgAAEAAAAcOAAA 1
互换后v_t就变成和t1的rowid一样了,好像是跟建view时驱动表的顺序有关。如果创建视图时t2放后面那么取的就是t2的rowid,t1放后面取的就是t1的rowid,这个大家可以找各种不同的情况再测试一下,在我的测试环境里面是这样的。
如果两张表的关联列上没有唯一约束或主建的话那么将不能查询视图的rowid
SQL 10G>alter table t1 drop constraints pk_t1;
Table altered.
SQL 10G>alter table t2 drop constraints pk_t2;
Table altered.
SQL 10G>select rowid from v_t;
select rowid from v_t
*
ERROR at line 1:
ORA-01445: cannot select ROWID from, or sample, a join view without a
key-preserved table
这是因为非key_preserved table不能保证关联的一对一,所以当选取rowid时将会出错。
关于key_preserved table tom有很好的例子