ITPub博客

首页 > 数据库 > Oracle > 不经意发现的dba_objects和dba_tables中的细节

不经意发现的dba_objects和dba_tables中的细节

原创 Oracle 作者:jeanron100 时间:2015-12-23 23:33:38 0 删除 编辑
今天有一个同学问我一个问题,因为白天比较忙也没有在意,在下班后坐地铁的时候抽空看了这个问题,感觉还是蛮有意思的。但是当时也没有任何答案,就准备自己回去好好实验一下再做答复,至少不能敷衍别人嘛。
他的问题大体思路如下,查看sys用户下object_type为TABLE的对象
SQL> select owner,count(*) from dba_objects where object_type='TABLE' and owner='SYS' group by owner;
OWNER                            COUNT(*)
------------------------------ ----------
SYS                                  1007
然后查看dba_tables中owner为sys的表
SQL> select owner,count(*)from dba_tables where owner='SYS' group by owner;

OWNER                            COUNT(*)
------------------------------ ----------
SYS                                   994
这两个语句看起来表达的意思应该相同,但是查出来的结果却出人意料,这位同学的疑问也再次。
于是我写了下面这个语句,可以看到确实有10多个不同的对象,但是object_type确实为TABLE
select owner,object_name,object_type from dba_objects where object_type='TABLE' and owner='SYS' and object_name not in (select table_name from dba_tables where owner='SYS') ;
OWNER           OBJECT_NAME                    OBJECT_TYPE
--------------- ------------------------------ -------------------
SYS             KOTTD$                         TABLE
SYS             KOTTB$                         TABLE
SYS             KOTAD$                         TABLE
SYS             KOTMD$                         TABLE
SYS             KOTTBX$                        TABLE
SYS             KOTADX$                        TABLE
SYS             S_PROPS_TAB                    TABLE
SYS             PROPERTIES_TAB                 TABLE
SYS             USR_PROPERTIES_TAB             TABLE
SYS             SCHEDULER$_RJQ_ANT             TABLE
SYS             SCHEDULER$_FWQ_ANT             TABLE
SYS             SYSNTIzu9FjIBDzDgUy2FfwrwMA==  TABLE
SYS             SYSNTIzu9FjIDDzDgUy2FfwrwMA==  TABLE
SYS             SYSNTIzu9FjIFDzDgUy2FfwrwMA==  TABLE
SYS             SYSNT5LbVzBZPECLgQ6yq6ApJJw==  TABLE
SYS             SYSNT5LbVzBZRECLgQ6yq6ApJJw==  TABLE
SYS             SYSNT5LbVzBZTECLgQ6yq6ApJJw==  TABLE
SYS             SYSNTIzu9FjIKDzDgUy2FfwrwMA==  TABLE
SYS             SYSNTIzu9FjIMDzDgUy2FfwrwMA==  TABLE
SYS             SYSNTIzu9FjIODzDgUy2FfwrwMA==  TABLE
20 rows selected.
这个结果是在11.2.0.4.0的环境中的,在12c中会有一些差别。
而且更奇怪的是使用desc命令直接无效,也不提示错误,也没有输出结果。
SQL> desc "KOTAD$"

SQL> desc KOTADX$

当然使用count(*)来查看数据条数,却能显示出来。
SQL> select count(*)from KOTADX$;
  COUNT(*)
----------
         3
如果尝试查看这个table的内容,也给出ORA错误。
SQL> select * from KOTADX$;
select * from KOTADX$
              *
ERROR at line 1:
ORA-30732: table contains no user-visible columns

SQL> select count(*)from KOTAD$;
  COUNT(*)
----------
     22511
对于这个错误,官方的解释如下: 
SQL> !oerr ora 30732
30732, 00000, "table contains no user-visible columns"
// *Cause:    An attempt was made to query on a system table which has no
//            user-visible columns.
// *Action:   Do not query on a system table that has no user-visible
//            columns.     
那么这个问题看起来是一个蛮神秘的细节,是不是和回收站有关系呢,我随机用了一个环境测试。
查看一个普通用户下,回收站中存在几个表。
SQL> select  * from cat;
TABLE_NAME                     TABLE_TYPE
------------------------------ -----------
BIN$JGiHLuOWWNvgUy2FfwrNqg==$0 TABLE
BIN$JGiHLuOXWNvgUy2FfwrNqg==$0 TABLE
CS_MONGO_SYNC_ID               TABLE
。。。
19 rows selected.
然后使用同样的语句来测试,使用dba_objects,以object_type='TABLE'过滤,得到17条纪录。
SQL>  select owner,count(*) from dba_objects where object_type='TABLE' and owner='TEST' group by owner;
OWNER                            COUNT(*)
------------------------------ ----------
TEST                                   17
使用dba_tables来过滤,得到17条纪录。
SQL> select owner,count(*)from dba_tables where owner='TEST' group by owner;
OWNER                            COUNT(*)
------------------------------ ----------
TEST                                   17
所以两者的数据条数是一致的,可见这个问题不是因为回收站导致的,那么问题的原因在哪呢。
其实还有一个部分可能会被遗忘,那就是对象表,我们使用下面的语句来查看。使用的是sys用户。可以看到这些都是对象表。
SQL> select table_name,table_type from user_object_tables;
TABLE_NAME                     TABLE_TYPE
------------------------------ ------------------------------
SYSNTIzu9FjIBDzDgUy2FfwrwMA==  KUPC$_FILEINFO
SYSNTIzu9FjIDDzDgUy2FfwrwMA==  KU$_LOGLINE1010
SYSNTIzu9FjIFDzDgUy2FfwrwMA==  KU$_LOGLINE1010
SYSNTIzu9FjIKDzDgUy2FfwrwMA==  KUPC$_FILEINFO
SYSNTIzu9FjIMDzDgUy2FfwrwMA==  KU$_LOGLINE1010
SYSNTIzu9FjIODzDgUy2FfwrwMA==  KU$_LOGLINE1010
KOTTD$                         KOTTD
KOTTB$                         KOTTB
KOTAD$                         KOTAD
KOTMD$                         KOTMD
KOTTBX$                        KOTTBX
KOTADX$                        KOTADX
S_PROPS_TAB                    DBMS_DBFS_CONTENT_PROPERTY_T
PROPERTIES_TAB                 DBMS_DBFS_CONTENT_PROPERTY_T
USR_PROPERTIES_TAB             DBMS_DBFS_CONTENT_PROPERTY_T
SCHEDULER$_RJQ_ANT             SCHEDULER$_REMOTE_ARG
SCHEDULER$_FWQ_ANT             SCHEDULER_FILEWATCHER_REQUEST
SYSNT5LbVzBZPECLgQ6yq6ApJJw==  KUPC$_FILEINFO
SYSNT5LbVzBZRECLgQ6yq6ApJJw==  KU$_LOGLINE1010
SYSNT5LbVzBZTECLgQ6yq6ApJJw==  KU$_LOGLINE1010
20 rows selected.

这个时候,可以从官网得到一些更详细的信息。官方的解释如下:

USER_OBJECT_TABLES describes the object tables owned by the current user. This view does not display the OWNER column.

那么我们想得到更明细的信息,其实还是有办法的,比如使用metadata得到ddl语句。
SELECT dbms_metadata.get_ddl('TABLE', 'KOTAD$', 'SYS')  FROM DUAL;
  CREATE TABLE "SYS"."KOTAD$" OF "SYS"."KOTAD"
 OIDINDEX  ( PCTFREE 10 INITRANS 2 MAXTRANS 255
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM" )
 PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "SYSTEM"
所以这些信息就会一览无余的暴露在我们面前,如果想了解更多的信息,就看看对象表的内容吧。这也是关系型之外的兼容,也可以说扩展吧。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23718752/viewspace-1880204/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
技术文章每天更新,阵地已转移到微信公众号端。 公众号:jianrong-notes

注册时间:2012-05-14

  • 博文量
    1498
  • 访问量
    14407415