一直认为,表被删除后,普通的视图中是查询不到表信息的,只有从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。