分区表相关视图没有过滤删除表

一直认为,表被删除后,普通的视图中是查询不到表信息的,只有从RECYCLBIN相关视图才能看到被删除的表,没想到最近发现分区表的相关视图中仍然保留被删除表的信息。
看一个简单的例子:

SQL> CREATE TABLE T_PART (ID NUMBER, NAME VARCHAR2(30))
  2  PARTITION BY HASH (ID)
  3  PARTITIONS 4;
表已创建。
SQL> SELECT TABLE_NAME, PARTITIONING_TYPE, PARTITION_COUNT, STATUS
  2  FROM USER_PART_TABLES;
TABLE_NAME                     PARTITION PARTITION_COUNT STATUS
------------------------------ --------- --------------- --------
T_PART                         HASH                    4 VALID
SQL> SELECT TABLE_NAME, PARTITION_NAME, PARTITION_POSITION 
  2  FROM USER_TAB_PARTITIONS;
TABLE_NAME                     PARTITION_NAME                 PARTITION_POSITION
------------------------------ ------------------------------ ------------------
T_PART                         SYS_P61                                         1
T_PART                         SYS_P62                                         2
T_PART                         SYS_P63                                         3
T_PART                         SYS_P64                                         4
SQL> SELECT TABLE_NAME, STATUS, DROPPED
  2  FROM USER_TABLES
  3  WHERE TABLE_NAME = 'T_PART';
TABLE_NAME                     STATUS   DRO
------------------------------ -------- ---
T_PART                         VALID    NO

建立一个分区表,可以从分区相关的数据字典中查询到这个分区表的信息,下面删除这个表:

SQL> DROP TABLE T_PART;
表已删除。
SQL> SELECT TABLE_NAME, PARTITIONING_TYPE, PARTITION_COUNT, STATUS
  2  FROM USER_PART_TABLES;
TABLE_NAME                     PARTITION PARTITION_COUNT STATUS
------------------------------ --------- --------------- --------
BIN$dtFNG1JsS26GLpXZhpv56A==$0 HASH                    4 VALID
SQL> SELECT TABLE_NAME, PARTITION_NAME, PARTITION_POSITION 
  2  FROM USER_TAB_PARTITIONS;
TABLE_NAME                     PARTITION_NAME                 PARTITION_POSITION
------------------------------ ------------------------------ ------------------
BIN$dtFNG1JsS26GLpXZhpv56A==$0 SYS_P61                                         1
BIN$dtFNG1JsS26GLpXZhpv56A==$0 SYS_P62                                         2
BIN$dtFNG1JsS26GLpXZhpv56A==$0 SYS_P63                                         3
BIN$dtFNG1JsS26GLpXZhpv56A==$0 SYS_P64                                         4
SQL> SELECT TABLE_NAME, STATUS, DROPPED
  2  FROM USER_TABLES
  3  WHERE TABLE_NAME = 'T_PART';
未选定行
SQL> SELECT TABLE_NAME, STATUS, DROPPED
  2  FROM USER_TABLES
TABLE_NAME                     STATUS   DRO
------------------------------ -------- ---
SERVICES                       VALID    NO
COMPANIES                      VALID    NO
SERVICE_USERS                  VALID    NO
SERVICE_USAGE                  VALID    NO
SERVICE_RATES                  VALID    NO
T_DEFER                        VALID    NO
T                              VALID    NO
T_P                            VALID    NO
T_F                            VALID    NO
MLOG$_T_P                      VALID    NO
MLOG$_T_F                      VALID    NO
MV_T_ORACLE                    VALID    NO
T_LOAD_LOB                     VALID    NO
已选择13行。

显然表被删除后,记录从USER_TABLES表中被过滤,但是在USER_PART_TABLES和USER_TAB_PARTITIONS中记录仍然存在。这说明Oracle的视图的一致性工作做的并不好,导致视图中包含的记录性质不统一。
那么查询分区相关视图,需要关联*_TABLES视图,才能获取到当前没有被删除的分区表或表分区信息。当然如果对于严谨性要求不是那么高的话,通过表名进行过滤也是一个比较准确且简单易行的方法。
最后提一下,*_TABLES视图中的DROPPED列似乎并没有什么意义,因为被删除的对象已经从视图中被过滤,怀疑Oracle在设计字段和视图的时候并没有考虑好,从DBA_TABLES视图中可以发现,所有的记录这个值都是NO。

This entry was posted in ORACLE and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *