今天有一个同学问我一个问题,因为白天比较忙也没有在意,在下班后坐地铁的时候抽空看了这个问题,感觉还是蛮有意思的。但是当时也没有任何答案,就准备自己回去好好实验一下再做答复,至少不能敷衍别人嘛。

他的问题大体思路如下,查看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/,如需转载,请注明出处,否则将追究法律责任。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐