2009-10-13 47 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。

相关问题