在Oracle中搜索LONG数据类型

问题描述 投票:1回答:2

我正在寻找一种方法来搜索具有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 oracle12c
2个回答
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;

2
投票

如果你查询ALL_VIEWSDBA_VIEWS,你会发现视图的定义USER_TAB_SUBPARTITIONS

SELECT TEXT
  FROM all_views
 WHERE view_name = 'USER_TAB_SUBPARTITIONS';

你会看到HIGH_VALUE来自hiboundvalsys.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文章

© www.soinside.com 2019 - 2024. All rights reserved.