2009-10-13 30 views
0

在我們的存儲過程中,我們有以下代碼到最後。<<SQL_ERROR>> block

<<SQL_ERROR>> 
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252); 

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE'); 

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' || 
         V_SYS_ERROR_MSG); 

我們有像以下這調用錯誤塊語句。

IF V_SYS_ERROR <> 0 THEN 
    GOTO SQL_ERROR; 

即使沒有錯誤,DBMS輸出語句也會出現。我們如何避免這種情況?

回答

2

推薦這種做法GOTO:正如其他人已經說過,例外是來處理PL/SQL錯誤的正確方法。但是,以解決您的具體問題,你可以這樣做:

BEGIN 
    IF V_SYS_ERROR <> 0 THEN 
    GOTO SQL_ERROR; 
    END IF; 

    GOTO PROC_END; 

    <<SQL_ERROR>> 
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252); 

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE'); 

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' || 
         V_SYS_ERROR_MSG); 

    <<PROC_END>> 
    NULL; 
END; 

當然,這還涉及到改變代碼,所以如果你這樣做,爲什麼不這樣做正確呢?即

DECLARE 
    SQL_ERROR EXCEPTION; 
BEGIN 
    IF V_SYS_ERROR <> 0 THEN 
    RAISE SQL_ERROR; 
    END IF; 

EXCEPTION 

    WHEN SQL_ERROR THEN 
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252); 

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE'); 

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' || 
         V_SYS_ERROR_MSG); 
    RAISE; 

END; 

順便提一下,DBMS_OUTPUT.PUT_LINE不適合於在生產應用程序的系統錯誤消息的輸出。僅在開發過程中將其用於調試。

2

你應該避免使用GOTO語句,因爲你已經注意到它們是混亂的。 PL/SQL自帶的錯誤處理,你應該使用異常synthax處理錯誤:

BEGIN 
    <code goes here> 
EXCEPTION 
    WHEN <exception> THEN 
     <deal_with_it> 
    WHEN OTHERS THEN 
     <log_error> 
     RAISE; 
END; 
+0

您提到的方式,我們將不得不在異常發生時處理異常?但是,這對我們來說不是一個好選擇。我們正在將大量的sql server存儲過程轉換爲oracle,並使用我們使用的工具(sql開發人員)製作了goto語句。我們討厭進入每個SP並開始搞亂邏輯 – Omnipresent 2009-10-13 15:33:57

+0

@Omnipresent:當你說「SQL開發者」時,你是指Oracle SQL Developer還是其他一些同名的工具? – 2009-10-14 10:09:19

+0

Oracle sql Developer – Omnipresent 2009-10-15 18:11:05

1

我不認爲你會得到你想要的結果,而無需使用異常處理程序。從PL/SQL用戶指南:

SQLERRM不帶參數只在異常處理是有用的 。外部 處理程序,無參數 SQLERRM始終返回正常,成功 完成消息。

因此,首先可能會發生錯誤,但您會看到一條消息,指出「正常,成功完成」,因爲這是SQLERRM在此上下文中始終返回的內容。

假設情況並非如此,聽起來好像你只是讓控制從「普通」代碼流入「錯誤處理程序」。如果錯誤處理程序位於過程的最後,那麼一個簡單的修復就是在<>標籤之前添加一個RETURN語句。

更好的解決方法是將錯誤處理程序代碼移動到單獨的過程並調用該過程而不是使用GOTO。

相關問題