2012-04-24 5 views
2

Я пытаюсь получить имя текущего раздела из таблицы all_tab_partitions. Когда я пытаюсь сравнить high_value (длинный тип данных) и номер. Он выдает ошибку:oracle long to number conversion

ORA-00997: illegal use of LONG datatype

SELECT PARTITION_NAME, HIGH_VALUE FROM ALL_TAB_PARTITIONS 
WHERE TABLE_OWNER='SCHEMA_NAM' 
AND TABLE_NAME='TABLE_NAME' 
AND HIGH_VALUE>to_number(TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, 1), 'MONTH'), 'YYYYDDD')) 
/
+0

Что такое ошибка? –

+0

ORA-00997: незаконное использование LONG-типа данных – mahen

ответ

6

Длинные типа хранит большие строки переменной длина символов, это НЕ числовой тип. У этого есть много ограничений. документации Oracle говорит:

Использование длинных значений подчиняется этим ограничениям:

  • Таблица может содержать только один LONG столбец.
  • Вы не можете создать тип объекта с атрибутом LONG.
  • Столбцы LONG не могут отображаться в WHERE или в ограничениях целостности (за исключением того, что они могут появляться в ограничениях NOT и NULL).
  • Столбцы LONG не могут быть проиндексированы.
  • LONG не может быть указан в регулярных выражениях.
  • Сохраненная функция возвращает значение LONG.
  • Вы можете объявить переменную или аргумент программного модуля PL/SQL с использованием типа данных LONG. Однако вы не можете вызывать программный блок из SQL.
  • В рамках одного оператора SQL, столбцы LONG, обновленные таблицы и заблокированные таблицы должны быть расположены в одной базе данных. Столбцы LONG и LONG RAW не могут использоваться в распределенных операциях SQL и не могут быть реплицированы.
  • Если таблица имеет как LONG, так и LOB-столбцы, вы не можете связывать более 4000 байтов данных как с столбцами LONG, так и с LOB в одном и том же заявлении SQL. Однако вы можете привязать более 4000 байтов данных к столбцу LONG или LOB.
3

Для того, чтобы исследовать или использовать значение LONG колонки вам придется написать несколько PL/SQL, подобный

DECLARE 
    strHigh_value VARCHAR2(4000); 
BEGIN 
    FOR aRow IN (SELECT PARTITION_NAME, HIGH_VALUE 
       FROM ALL_TAB_PARTITIONS 
       WHERE TABLE_OWNER = 'SCHEMA_NAM' AND 
         TABLE_NAME = 'TABLE_NAME') 
    LOOP 
    strHigh_value := aRow.HIGH_VALUE; 

    -- TODO: Manipulate strHigh_value in whatever manner you need 

    END LOOP; 
END; 

Share и наслаждайтесь.

0

Если вы не хотите писать PL/SQL попытаться использовать (в общем случае):

select 
    sys.dbms_metadata_util.long2varchar(4000, 'TABLE_NAME', 'COLUMN_NAME', tp.rowid) as COLUMN_NAME 
from 
    TABLE_NAME tp 
where 
    <your_condition on table TABLE_NAME> 

не используют COLUMN_NAME в ... your_condition на столе TABLE_NAME ...

В вашем случае это немного сложнее, потому что вы запрашиваете VIEW. Нужно копаться в коде представления и переписать запрос как:

select PARTITION_NAME, HIGH_VALUE from (
    select t.PARTITION_NAME, sys.dbms_metadata_util.long2varchar(4000, 'SYS.TABCOMPART$', 'HIBOUNDVAL', tp.rowid) as high_value 
    from 
     all_tab_partitions t, sys.obj$ o, sys.tabcompart$ tp 
    where 
     t.table_name = 'TABLE_NAME' 
     and t.table_owner = 'SCHEMA_NAM' 
     and o.name = t.table_name 
     and o.subname = t.partition_name 
     and o.obj# = tp.obj#(+) 
) 
where 
    high_value > to_number(TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, 1), 'MONTH'), 'YYYYDDD')) 

протестирован на Oracle 11g