2013-11-21 93 views
0

我使用Oracle 11g,嘗試使用PL/SQL將90天以前的任何內容移動到歷史記錄表中。但我有一個使用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:從Oracle 9出來以後,'LONG'數據類型就被棄用了。 –

+0

這是該表自創建以來的數據類型..我可以檢查DBA以更改爲BLOB,但是如果表中已經包含數據,是否有任何更改列的數據類型的問題。 ....只有一年的經驗,所以還沒有遇到很多這些情況呢.. – user3017849

回答

1

長數據類型一直是我一直建議不要將文檔或長字符串存儲在Oracle數據庫中的原因之一。如果不恢復到C和OCI,則很難使用。

現在我們有可以在PL/SQL和SQL中合理使用的clob和blob。但是,在Oracle數據字典中,仍然會發現很多可以找到的LONG數據類型。特別是在XXX_VIEWS(user_views,all_views,dba_views)中,這是一個真正的問題。也許最初的開發者應該把它命名爲UNUSABLE :-)。

當LONG內容小於32 KB時有一種解決方法;對於完整的功能,我建議遷移到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;