这样我们可以通过这个函数将LONG类型的数据转换为VARCHAR2类型的数据,从而得到最终的结果。
执行查询
SELECT *
FROM user_tab_partitions
WHERE
UPPER(sys.dbms_metadata_util.long2varchar(1000,
'USER_TAB_PARTITIONS', 'HIGH_VALUE', ROWID)) = 'DEFAULT'
返回错误信息:
第 1 行出现错误:
ORA-01446: 无法使用 DISTINCT, GROUP BY 等子句从视图中选择 ROWID 或采样。
由于USER_TAB_PARTITIONS不是基本表,因此不存在ROWID,看来sys.dbms_metadata_util.long2varchar2只对基本表有效。
2. 步骤2
下面我们就通过USER_TAB_PARTITIONS找到其基本表。
连接到sys用户下,执行:
SELECT owner, object_name, object_type
FROM DBA_OBJECTS
WHERE OBJECT_NAME='USER_TAB_PARTITIONS'
得到结果如下:
OWNER
OBJECT_NAME
OBJECT_TYPE
SYS
USER_TAB_PARTITIONS
VIEW
PUBLIC
USER_TAB_PARTITIONS
SYNONYM
这里发现USER_TAB_PARTITIONS是一个视图,取得这个视图的脚本。
SELECT DBMS_METADATA.GET_DDL(‘VIEW’,’ USER_TAB_PARTITIONS’)
FROM DUAL;
完整的查询结果这里不再给出,通过查询可以了解到USER_TAB_PARTITIONS的HIGH_VALUE对应tabpartv$.
Hiboundval,tabpartv$表其他的关键字段还有
Obj# 分区对象的对象号,对应dba_objects.object_id
Dataobj# 分区对象的数据对象号,对应dba_objects.data_object_id
Bo# 分区表对应的对象号,对应dba_objects.object_id(记录对应为表)
Part# 分区表号,对应user_tab_partitions. partition_position
这样,我们只要执行下面的查询就可以了,
SELECT *
FROM tabpartv$
WHERE
sys.dbms_metadata_util.long2varchar(10, 'SYS.TABPARTV$',
'HIBOUNDVAL', ROWID) = 'DEFAULT'
根据得到的结果,我们利用user_objects查询对应的obj#,然后再查询USER_TAB_PARTITIONS就可以了。要指定特定的用户,比如SCOTT用户下的分区数据,还要关联obj$和user$基础表。
下面用一个SQL得到我们想要的结果,
SELECT a.* FROM dba_tab_partitions a JOIN dba_objects b
ON(a.table_owner=b.owner AND
a.table_name=b.object_name and
a.partition_name=b.subobject_name)
WHERE b.object_id IN(
SELECT a.obj#
FROM tabpartv$ a join obj$ b
ON(a.obj#=b.obj#)
JOIN user$ c
ON(b.owner#=c.user#)
WHERE
UPPER(sys.dbms_metadata_util.long2varchar(10, 'SYS.TABPARTV$',
'HIBOUNDVAL', A.ROWID)) = 'DEFAULT'
AND c.name=’SCOTT’)