2013-11-21 2 views
0

Я использую Oracle 11g, пытаясь переместить что-нибудь старше 90 дней в таблицу Истории, используя PL/SQL..BUT У меня есть один из столбцов, использующих тип данных LONG. Таким образом, я нашел SQL, что я думал, должны работать, но это дает ошибки:PLSQL архивирование LONG тип данных, ошибка:

BEGIN 
FOR ROW IN 
     (SELECT MESSSAGE_KEY, 
      DISTRIBUTION_ID, 
      MESSAGE, 
      SYSTEM_NAME, 
      MESSAGE_TYPE, 
      MESSAGE_NAME, 
      MESSAGE_STATUS, 
      LATEST_INBOUND, 
      CREATETS, 
      MODIFYTS, 
      CREATEUSERID, 
      MODIFYUSERID, 
      CREATEPROGID, 
      MODIFYPROGID, 
      LOCKID, 
      ENTITY_KEY, 
      ENTITY_NAME, 
      ENTITY_VALUE 
     FROM NWCG_INBOUND_MESSAGE 
     WHERE TO_CHAR (createts, 'YYYYMMDD') >= TO_CHAR ((sysdate-90), 'YYYYMMDD') 
    ) 
    LOOP 
    INSERT INTO NWCG_INBOUND_MESSAGE_H 
    VALUES ( 
       ROW.MESSSAGE_KEY, 
      ROW.DISTRIBUTION_ID, 
      ROW.MESSAGE, 
      ROW.SYSTEM_NAME, 
      ROW.MESSAGE_TYPE, 
      ROW.MESSAGE_NAME, 
      ROW.MESSAGE_STATUS, 
      ROW.LATEST_INBOUND, 
      ROW.CREATETS, 
      ROW.MODIFYTS, 
      ROW.CREATEUSERID, 
      ROW.MODIFYUSERID, 
      ROW.CREATEPROGID, 
      ROW.MODIFYPROGID, 
      ROW.LOCKID, 
      ROW.ENTITY_KEY, 
      ROW.ENTITY_NAME, 
      ROW.ENTITY_VALUE 
      ); 
END LOOP; 
END; 

Это ошибка, я получаю:

Error report: 
ORA-06502: PL/SQL: numeric or value error 
ORA-06512: at line 2 
06502. 00000 - "PL/SQL: numeric or value error%s" 
*Cause:  
*Action: 

Из моих исследований, похоже, эта ошибка была около много, но я не могу найти какие-либо решения людей для работы ... любые идеи?

+0

Я могу видеть, что я написал «to_char (createts,„YYYYMMDD“)> = TO_CHAR ((..» это было только для тестирования, как я не хотел тратить слишком долго выполняющиеся выбора лет данных – user3017849

+1

Почему вы используете цикл? Вы можете сделать это с помощью одного оператора INSERT ... SELECT, который определенно намного быстрее, чем цикл PL/SQL. Btw: тип данных 'LONG' устарел, поскольку Oracle 9 вышел Почему он все еще используется? –

+0

Это тип данных, с которых была создана таблица. Я могу проверить с помощью DBA, чтобы он изменился на BLOB, но есть ли какие-либо проблемы при изменении типов данных столбцов, если таблица уже содержит данные. .... ive всего лишь многолетний опыт, так что havent натолкнулся на многие из этих ситуаций. – user3017849

ответ

1

Длинный тип данных был одной из причин, по которым я всегда советовал не хранить документы или длинную строку в базе данных Oracle. Не возвращаясь к C и OCI, его трудно использовать.

Теперь у нас есть clob и blob, которые разумно использовать в PL/SQL и SQL. Но по-прежнему существует много вхождений этого типа данных LONG, также в словарь данных Oracle. Особенно в XXX_VIEWS (user_views, all_views, dba_views) это реальная проблема. Возможно, оригинальный разработчик должен был назвать его UNUSABLE :-).

Существует временное решение, когда содержание LONG меньше 32 КБ; для полной функциональности я бы рекомендовал перейти на CLOB или использовать C. Удачи!

-- 
-- This sample code works when the long is smaller than 32 KB. 
-- It is known to work on 9i, 10g, 11g r1, 11g r2, but it assumes 
-- that a LONG smaller than 32 KB can be put in a PL/SQL variable. 
-- And then cast. 
-- 
-- You might want to add an exception handler to handle exceptions 
-- when the size is larger than 32 KB. In this sample, this situation 
-- can not occur; the where clause with text_length ensures that. 
-- 
declare 
    l_text_as_long long; 
    l_text_as_clob clob; 
    l_text_length user_views.text_length%type; 
begin 
    select viw.text 
    ,  viw.text_length 
    into l_text_as_long 
    ,  l_text_length 
    from user_views viw 
    where viw.view_name = upper(l_object_name) 
    and viw.text_length <= 32767 /* To fix a problem when accessing a view that is larger than 32K, we have this condition. */ 
    ; 
    l_text_as_clob := cast(l_text_as_long as clob); 
    ... do something interesting ... 
end; 
Смежные вопросы