Chinaunix首页 | 论坛 | 博客
  • 博客访问: 141074
  • 博文数量: 161
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -30
  • 用 户 组: 普通用户
  • 注册时间: 2017-09-21 21:45
文章分类
文章存档

2009年(1)

2008年(74)

2007年(48)

2006年(38)

我的朋友

分类: Oracle

2007-06-11 12:28:27

 

大家都知道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有很好的例子
 
 
阅读(1069) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~