2011-11-08 70 views
2

我有以下函數,我從同一個pl/sql包中的另一個程序調用。pl/sql'Function'中的異常塊沒有捕獲錯誤條件

Function lf_get_query(p_table in varchar2) return varchar2 
Is 
    v_where_clause varchar2(500); 
Begin 
    Case upper(p_table) 
     When 'TABLEA' then      
      v_where_clause := ' Where trunc(x.purchase_dtm) < ' || '''' || trunc(v_check_Date) || ''''; 
     When 'TABLEB' then      
      v_where_clause := ' Where trunc(x.purchase_dtm) < ' || '''' || trunc(v_check_Date) || '''' 
           || ' And product_type='ABC' 
           || ' And customer_type='XXX' 
           || ' And contract_type='YYY'; 
     Else 
      raise ex_unknown_table_type;      
    End case;   
    return v_where_clause; 
Exception 
    When ex_unknown_table_type then 
     [[Log to file that table is urecognised. ]] 
     raise; 
    When others then 
     [[Log to file that table is urecognised and include sqlerrm ]] 
     raise; 
End; 

當我打電話的功能,它會生成以下錯誤:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small 

生成該錯誤,因爲變量v_where_clause不是爲某些字符串我試圖在存儲的足夠大變量。我不明白的是當錯誤發生時,它不會被上面顯示的兩個異常條款中的任何一個捕獲。相反,正在調用此函數的過程的異常塊上正在捕獲錯誤。

我知道它沒有被函數中的異常子句捕獲的原因是這兩個異常子句都應該將錯誤條件記錄到文件中,但它們不是。

這是否有任何理由? 「WHEN OTHERS」時段的例外情況是否應該抓住例外情況?

此外,有沒有什麼辦法可以聲明v_where_clause變量而不指定大小?

謝謝

+0

將您的VARCHAR2變量指定爲一個非常大的大小,即32767,Oracle會自動給它提供足夠的存儲以涵蓋您放入的內容。它不會任意留出32767字節。 – Ollie

回答

4

調用過程發出回滾的異常塊嗎?如果是這樣的話,它會和其他所有事件一起回滾你的日誌。解決此問題的方法是使用PRAGMA AUTONOMOUS_TRANSACTION定義的過程,該過程將允許您在當前事務之外進行日誌記錄。

+0

哦,我很愚蠢。正在回滾表中記錄的日誌條目。謝謝!!!!!!!! – ziggy

+2

發生在我們所有人至少一次;-) – DCookie

+0

+1寫作日誌記錄是* only *有效用於AUTONOMOUS TRANSACTION。 – APC