我正在寻找一种方法来搜索具有LONG数据类型的列。
我知道那些已被弃用(而且我一直讨厌与他们一起工作......),但由于某些原因,Oracle自己继续在他们自己的表和视图中使用它们......
基本上我想在SYS.USER_TAB_SUBPARTITIONS
上构建一个查询,WHERE子句过滤特定的HIGH_VALUE
。
HIGH_VALUE是LONG数据类型,我知道过滤这些东西的唯一方法是使用未记录的函数dbms_metadata_util.long2varchar
但是,使用此函数执行查询时,返回的值为NULL。
select sys.dbms_metadata_util.long2varchar(2000,'SYS.USER_TAB_SUBPARTITIONS','HIGH_VALUE', rowid) from USER_TAB_SUBPARTITIONS;
这很可能是因为USER_TAB_SUBPARTITIONS
实际上不是一个表,而是一个视图。并且视图没有rowid ......
但是,它似乎是一种奇怪的视图,因为它的定义没有显示任何底层基表。相反,它只是为自己创建一个同义词。
那么,对于我的实际问题:还有其他方法可以查询LONG吗?有谁知道USER_TAB_SUBPARTITIONS
的“基准表”?
是的,Oracle System-Views中的数据类型LONG
很痛苦。当我必须使用这样的值时,我使用这个:
DECLARE
high_value INTEGER;
BEGIN
FOR aPart IN (SELECT * FROM USER_TAB_SUBPARTITIONS) LOOP
EXECUTE IMMEDIATE 'BEGIN :ret := '||aPart.HIGH_VALUE||'; END;' USING OUT high_value;
SELECT ...
WHERE ... = high_value;
end loop;
END;
注意,在这个例子中,HIGH_VALUE
是一个整数值。但是,它可以是其他任何东西(例如TIMESTAMP),请在您的过程中考虑这一点。例如这样:
FUNCTION IntervalType(tableName IN VARCHAR2) RETURN VARCHAR2 IS
EXPRESSION_IS_OF_WRONG_TYPE EXCEPTION;
PRAGMA EXCEPTION_INIT(EXPRESSION_IS_OF_WRONG_TYPE, -6550);
ds INTERVAL DAY TO SECOND;
ym INTERVAL YEAR TO MONTH;
str VARCHAR2(1000);
BEGIN
SELECT INTERVAL
INTO str
FROM USER_PART_TABLES
WHERE TABLE_NAME = tableName;
EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT ym;
RETURN 'YEAR TO MONTH Interval of '||ym;
EXCEPTION
WHEN EXPRESSION_IS_OF_WRONG_TYPE THEN
EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT ds;
RETURN 'DAY TO SECOND Interval of '||ds;
END IntervalType;
如果你查询ALL_VIEWS
或DBA_VIEWS
,你会发现视图的定义USER_TAB_SUBPARTITIONS
SELECT TEXT
FROM all_views
WHERE view_name = 'USER_TAB_SUBPARTITIONS';
你会看到HIGH_VALUE
来自hiboundval
的sys.tabsubpart$
列。
我们还有另一种方法来提取HIGH_VALUE
。您可以使用SUBSTR()
从提取的HIGH_VALUE
中提取精确值。
DECLARE
v_high_value VARCHAR2(100);
BEGIN
SELECT EXTRACTVALUE (
DBMS_XMLGEN.GETXMLTYPE (
'SELECT high_value
FROM all_tab_partitions
WHERE partition_name='''
|| YOUR_PARTITION_NAME
|| '''
AND table_owner='''
|| YOUR_TABLE_OWNER
|| '''
AND table_name='''
|| YOUR_TABLE
|| ''''),
'ROWSET/ROW/HIGH_VALUE') INTO v_high_value
FROM DUAL;
END;
/
你可以在这里参考Ask TOM文章