印第安小白鼠
自我介绍
切换风格
订阅我的Blog
博客日历
文章归档...
最新发表...
博客统计...
网站链接...
资源
===========================================================
Desc 视图存在,select却报视图不存在的原因。
===========================================================


Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

C:Documents and Settingsvecentli>sqlplus /nolog

SQL*Plus: Release 9.2.0.1.0 - Production on 星期三 7月 13 09:32:28 2005

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

SQL> conn sys/********@oravis as sysdba
已连接。
SQL> grant select any table to ap;

授权成功。

SQL>

SQL> conn ap/********@oravis;
已连接。
SQL> desc tab
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------

TNAME NOT NULL VARCHAR2(30)
TABTYPE VARCHAR2(7)
CLUSTERID

SQL> select count(*)
2 from tab;

COUNT(*)
----------
255


SQL> desc scott.tab
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------

TNAME NOT NULL VARCHAR2(30)
TABTYPE VARCHAR2(7)
CLUSTERID NUMBER

SQL> select *
2 from scott.tab
3 ;
from scott.tab
*
ERROR 位于第 2 行:
ORA-00942: 表或视图不存在

SQL>

SQL> conn sys/************@oravis as sysdba
已连接。
SQL> desc tab
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------

TNAME NOT NULL VARCHAR2(30)
TABTYPE VARCHAR2(7)
CLUSTERID NUMBER

SQL> desc scott.tab
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------

TNAME NOT NULL VARCHAR2(30)
TABTYPE VARCHAR2(7)
CLUSTERID NUMBER

SQL> select *
2 from scott.tab;
from scott.tab
*
ERROR 位于第 2 行:
ORA-00942: 表或视图不存在


SQL>

dba权限的用户也不可以。。
只能desc其他用户的tab,而不能select其他用户的tab。。
看来不是权限的问题,难道oracle限制了这个做法?

----回过头来看看视图定义。

select o.name,
decode(o.type#, 2, 'TABLE', 3, 'CLUSTER',
4, 'VIEW', 5, 'SYNONYM'), t.tab#
from sys.tab$ t, sys.obj$ o
where o.owner# = userenv('SCHEMAID')
and o.type# >=2
and o.type# <=5
and o.linkname is null
and o.obj# = t.obj# (+);


肯定这个 userenv('SCHEMAID') 破玩意在作怪!

SQL> select userenv('SCHEMAID')
2 from dual;

USERENV('SCHEMAID')
-------------------
0

SQL>


SCHEMAID的解释.
SCHEMAID returns the id of the schema for the current user. This id is used, for example, in obj$ (column owner#).
select userenv('SCHEMAID') from dual;

--可是为什么会报 表或视图不存在的错误呢?应该是未选定行才对啊?!

猜测:

根椐下面的试验,我猜测DESC时如果指定了方案限定词时是查找用户的表,视图,私有同义词或者公有同义词,而SELECT的时候,如果指定了方案限定词,不会去查找公有同义词,所以才有这样的差别。

SQL> show user
USER is "WYQ"
SQL> select table_name from user_tables;

TABLE_NAME
------------------------------
PLAN_TABLE
T

SQL> desc t
Name Null? Type
----------------------------------------------------------------------- -------- ------------------------------------------------

X NOT NULL NUMBER
Y VARCHAR2(128)

SQL> create synonym syn_t for t;

Synonym created.

SQL> conn sys/wyq as sysdba
Connected.
SQL> desc wyq.syn_t
Name Null? Type
----------------------------------------------------------------------- -------- ------------------------------------------------

X NOT NULL NUMBER
Y VARCHAR2(128)

SQL> select count(*) from wyq.syn_t;

COUNT(*)
----------
100

SQL> conn wyq/wyq
Connected.
SQL> drop synonym syn_t;

Synonym dropped.

SQL> create public synonym syn_t for t;

Synonym created.

SQL> conn sys/wyq as sysdba
Connected.
SQL> desc wyq.syn_t;
Name Null? Type
----------------------------------------------------------------------- -------- ------------------------------------------------

X NOT NULL NUMBER
Y VARCHAR2(128)

SQL> select count(*) from wyq.syn_t;
select count(*) from wyq.syn_t
*
ERROR at line 1:
ORA-00942: table or view does not exist


SQL>

--做个trace验证一把。

sqlplus " /as sysdba"
alter session set events '10046 trace name context forever,level 12'
;
desc sys.TT (there's no object name TT in my db)
exit

some thing in the trace file.

PARSING IN CURSOR #1 len=198 dep=1 uid=0 oct=3 lid=0 tim=2205811854802 hv=2703824309 ad=
'91cfeb40'
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2 from obj$
where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is nu
ll and subname is null
END OF STMT
PARSE #1:c=0,e=3248,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=0,tim=2205811854790
BINDS #1:
bind 0: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=08 oacfl2=1 size=24 offset=0
bfp=ffffffff7d069640 bln=22 avl=03 flg=05
value=0
bind 1: dty=1 mxl=32(02) mal=00 scl=00 pre=00 oacflg=18 oacfl2=1 size=32 offset=0
bfp=ffffffff7d069608 bln=32 avl=02 flg=05
value="TT"
bind 2: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=08 oacfl2=1 size=24 offset=0
bfp=ffffffff7d0695d8 bln=24 avl=02 flg=05
value=1
EXEC #1:c=10000,e=3068,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=3,tim=2205811858366
FETCH #1:c=0,e=310,p=0,cr=3,cu=0,mis=0,r=0,dep=1,og=3,tim=2205811858772
BINDS #1:
bind 0: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=08 oacfl2=1 size=24 offset=0
bfp=ffffffff7d069640 bln=22 avl=02 flg=05
value=1
bind 1: dty=1 mxl=32(02) mal=00 scl=00 pre=00 oacflg=18 oacfl2=1 size=32 offset=0
bfp=ffffffff7d069608 bln=32 avl=02 flg=05
value="TT"
bind 2: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=08 oacfl2=1 size=24 offset=0
bfp=ffffffff7d0695d8 bln=24 avl=02 flg=05

上面红色部分是owner# 的bind 值

1 select name,user#
2* from user$ where user# in (0,1)
SQL> /
PUBLIC 1
SYS 0

可以看出,Oracle先根据“SYS”(owner#=0) 找,没找到,于是就到“public” (owner#=1) 里找
....
--继续做select的trace。

SQL> alter session set events '10046 trace name context forever,level 12'
2 /

Session altered.

SQL> select * from sys.TT
2 /
select * from sys.TT
*
ERROR at line 1:
ORA-00942: table or view does not exist

可以方向在trace file里只找了"SYS”(owner#=0) 的object
PARSING IN CURSOR #3 len=198 dep=1 uid=0 oct=3 lid=0 tim=2206623598500 hv=2703824309 ad=
'91cfeb40'
select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, spare2 from obj$
where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is nu
ll and subname is null
END OF STMT
PARSE #3:c=0,e=139,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=3,tim=2206623598489
BINDS #3:
bind 0: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=08 oacfl2=1 size=24 offset=0
bfp=ffffffff7d068d78 bln=22 avl=01 flg=05
value=0
bind 1: dty=1 mxl=32(02) mal=00 scl=00 pre=00 oacflg=18 oacfl2=1 size=32 offset=0
bfp=ffffffff7d068d40 bln=32 avl=02 flg=05
value="TT"
bind 2: dty=2 mxl=22(22) mal=00 scl=00 pre=00 oacflg=08 oacfl2=1 size=24 offset=0
bfp=ffffffff7d068d10 bln=24 avl=02 flg=05
value=1
EXEC #3:c=0,e=621,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=3,tim=2206623599523
FETCH #3:c=0,e=252,p=0,cr=3,cu=0,mis=0,r=0,dep=1,og=3,tim=2206623599848
=====================
PARSE ERROR #2:len=21 dep=0 uid=0 oct=3 lid=0 tim=2206623600042 err=942
select * from sys.TT

conclusions:

DESC时如果指定了方案限定词时是查找用户的表,视图,私有同义词或者公有同义词,而SELECT的时候,如果指定了方案限定词,不会去查找公有同义词,所以才有这样的差别。


vecentli 发表于:2006.04.06 15:38 ::分类: ( Oracle ) ::阅读:(538次) :: 评论 (1) :: 引用 (0)
polo t shirts [回复]

polo t shirts Portable DVD players poster printing posters printing power leveling power leveling power leveling power leveling power leveling power leveling

polo t shirts 评论于:2009.07.04 11:37

发表评论
标题

在此添加评论

称呼

邮箱地址(可选)

个人主页(可选)