2010-04-29 26 views
4
create or replace procedure proc_advertisement(CustomerID in Number, 
NewspaperID in number, 
StaffID in Number, 
OrderDate in date, 
PublishDate in date, 
Type in varchar,  
Status in varchar, 
Units in number) is 

begin 

insert into PMS.Advertisement(CustomerID, NewspaperID, StaffID, OrderDate, PublishDate, 
Type, Status, Units) 
values(CustomerID,NewspaperID, StaffID, OrderDate, PublishDate, 
Type, Status, Units); 
dbms_output.put_line('Advertisement Order Placed Successfully'); 
end; 

如何檢查過程執行過程中是否發生錯誤,如果發生錯誤,則希望顯示錯誤消息。在oracle中執行過程時檢查錯誤

回答

7

首先,甲骨文本身如果出現任何錯誤,同時運行的程序產生錯誤信息 - 例如:

ORA-02291: integrity constraint (EMP.MGR_FK) violated - parent key not Found 

您可以通過編寫一個異常處理程序明確處理錯誤,但除非你這樣做那麼你很可能只是混淆了這個問題。

EXCEPTION 
    WHEN OTHERS THEN 
     RAISE_APPLICATION_ERROR(-20001,'An error occured'); 

但現在你的用戶不知道什麼樣的錯誤,而在此之前,他們可以推斷,這是指定的經理沒有:例如,你根本就只是你的程序結束之前加入這個( 。存在,您可以顯示原來的錯誤也是這樣:。

EXCEPTION 
    WHEN OTHERS THEN 
     RAISE_APPLICATION_ERROR(-20001,'An error occured: '||SQLERRM); 

如果增加任何價值或者你可以只顯示一個通用的錯誤,然後SQLERRM的值寫入日誌表

你也可以處理特定的例外情況:例如

PROCEDURE ... IS 
    e_invalid_fk EXCEPTION; 
    PRAGMA EXCEPTION_INIT(e_invalid_fk,-2291); 
BEGIN 
    ... 
EXCEPTION 
    WHEN e_invalid_fk THEN 
     IF SQLERRM LIKE '%(EMP.MGR_FK)%' THEN 
      raise_application_error(-20001,'Invalid manager specified'); 
     ELSE 
      RAISE; 
     END IF; 
END; 

注意RAISE:如果您的異常處理程序的任何部分不發出任何加薪或RAISE_APPLICATION_ERROR,那麼你有效地掃在地毯下的例外 - 用戶會認爲該程序的工作。

順便說一句,DBMS_OUTPUT.PUT_LINE非常適合在SQL Plus或IDE中嘗試和調試,但它在真實代碼中沒有位置,因爲調用該過程的用戶和應用程序永遠不會看到它生成的輸出。

+0

+1 - 提出了我將要做的所有要點,特別是DBMS_OUTPUT對錯誤處理的不適合性(在一些特殊情況下是例外)。 – APC 2010-04-29 09:29:56

+0

+1,我也喜歡raise_application_error(xxx,msg,** TRUE **),這樣就保存了錯誤堆棧。這對最終用戶和支持都是有用的。 – 2010-04-29 10:52:28

+0

我總是忘記第三個參數! – 2010-04-29 11:17:24