在Oracle中搜索LONG数据类型

时间:2018-03-01 08:42:29

标签: oracle oracle12c

我正在寻找一种使用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的“基本表”吗?

2 个答案:

答案 0 :(得分:2)

如果您查询ALL_VIEWSDBA_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;