我正在寻找一种使用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
的“基本表”吗?
答案 0 :(得分:2)
如果您查询ALL_VIEWS
或DBA_VIEWS
,您会找到视图的定义USER_TAB_SUBPARTITIONS
SELECT TEXT
FROM all_views
WHERE view_name = 'USER_TAB_SUBPARTITIONS';
您会看到HIGH_VALUE
来自hiboundval
的{{1}}列。
我们还有另一种方法来提取sys.tabsubpart$
。您可以使用HIGH_VALUE
从提取的SUBSTR()
中提取确切的值。
HIGH_VALUE
您可以在此处提及Ask TOM文章
答案 1 :(得分:2)
是的,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;