Oracle <&书信电报;SQL_错误>&燃气轮机;块

Oracle <&书信电报;SQL_错误>&燃气轮机;块,oracle,plsql,Oracle,Plsql,在我们的存储过程中,最后有以下代码 <<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_SY

在我们的存储过程中,最后有以下代码

  <<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);

V_SYS_ERROR_MSG:=SUBSTR(SQLERRM,1252);
DBMS_OUTPUT.PUT_行(“过程中执行错误”);
DBMS_OUTPUT.PUT_LINE('错误代码为'| | V| u SYS_ERROR | |'-'||
V_系统错误消息);
我们有如下语句调用错误块

  IF V_SYS_ERROR <> 0 THEN
    GOTO SQL_ERROR;
如果V_系统错误为0,则
转到SQL_错误;

即使没有错误,DBMS输出语句也会出现。我们怎样才能避免这种情况呢?

你应该避免使用GOTO语句,正如你所注意到的,它们很混乱。PL/SQL附带错误处理,您应该使用异常synthax来处理错误:

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

例外情况
什么时候
当其他人
提高;
结束;

你应该避免使用GOTO语句,正如你所注意到的那样,它们很混乱。PL/SQL附带错误处理,您应该使用异常synthax来处理错误:

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

例外情况
什么时候
当其他人
提高;
结束;

我认为如果不使用异常处理程序,您不会得到想要的结果。从PL/SQL用户指南中:

没有参数的SQLERRM很有用 仅在异常处理程序中。外面 不带参数的处理程序SQLERRM 始终返回正常的、成功的 完成消息

因此,首先,可能发生了错误,但您会看到一条消息说“正常,成功完成”,因为在这种情况下SQLERRM将始终返回该消息

假设情况并非如此,听起来您只是允许控制从“正常”代码流入“错误处理程序”。如果错误处理程序位于过程的最后,那么一个简单的修复方法是在标签之前添加一个RETURN语句


更好的解决方法是将错误处理程序代码移动到一个单独的过程中,并调用该过程,而不是使用GOTO。

我认为如果不使用异常处理程序,您将无法获得想要的结果。从PL/SQL用户指南中:

没有参数的SQLERRM很有用 仅在异常处理程序中。外面 不带参数的处理程序SQLERRM 始终返回正常的、成功的 完成消息

因此,首先,可能发生了错误,但您会看到一条消息说“正常,成功完成”,因为在这种情况下SQLERRM将始终返回该消息

假设情况并非如此,听起来您只是允许控制从“正常”代码流入“错误处理程序”。如果错误处理程序位于过程的最后,那么一个简单的修复方法是在标签之前添加一个RETURN语句


更好的解决方法是将错误处理程序代码移动到一个单独的过程中,并调用该过程,而不是使用GOTO。

我不推荐这种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;
开始
如果V_系统错误为0,则
转到SQL_错误;
如果结束;
转到进程结束;
V_SYS_ERROR_MSG:=SUBSTR(SQLERRM,1252);
DBMS_OUTPUT.PUT_行(“过程中执行错误”);
DBMS_OUTPUT.PUT_LINE('错误代码为'| | V| u SYS_ERROR | |'-'||
V_系统错误消息);
无效的
结束;
当然,这仍然需要更改代码,因此如果您正在这样做,为什么不正确地执行呢?i、 e

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;
声明
SQL_错误异常;
开始
如果V_系统错误为0,则
提出SQL_错误;
如果结束;
例外情况
当SQL_出错时
V_SYS_ERROR_MSG:=SUBSTR(SQLERRM,1252);
DBMS_OUTPUT.PUT_行(“过程中执行错误”);
DBMS_OUTPUT.PUT_LINE('错误代码为'| | V| u SYS_ERROR | |'-'||
V_系统错误消息);
提高;
结束;

顺便说一下,DBMS_OUTPUT.PUT_行不适合在生产应用程序系统中输出错误消息。只在开发过程中使用它进行调试。

我不推荐这种转到方法:正如其他人已经说过的,异常是处理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;
开始
如果V_系统错误为0,则
转到SQL_错误;
如果结束;
转到进程结束;
V_SYS_ERROR_MSG:=SUBSTR(SQLERRM,1252);
DBMS_OUTPUT.PUT_行(“过程中执行错误”);
DBMS_OUTPUT.PUT_LINE('错误代码为'| | V| u SYS_ERROR | |'-'||
V_系统错误消息);
无效的
结束;
当然,这仍然需要更改代码,因此如果您正在这样做,为什么不正确地执行呢?i、 e

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;
声明
SQL_错误异常;
开始
如果V_系统错误为0,则
提出SQL_错误;
如果结束;
例外情况
当SQL_出错时
V_SYS_ERROR_MSG:=SUBSTR(SQLERRM,1252);
DBMS_OUTPUT.PUT_行(“过程中执行错误”);
DBMS_OUTPUT.PUT_LINE('错误代码为'| | V| u SYS_ERROR | |'-'||
V_系统错误消息);
提高;
结束;

顺便说一下,DBMS_OUTPUT.PUT_行不适合在生产应用程序系统中输出错误消息。只在开发过程中使用它进行调试。

您提到的在异常发生时我们必须处理异常的方式对吗?然而,这对我们来说不是一个好的选择。我们正在将许多sql server存储过程转换为oracle,我们使用的工具(sql developer)生成了goto语句。我们不想进入每一个SP,开始搞乱它logic@Omnipresent:当您说“SQL开发人员”时,您是指Oracle SQL开发人员还是其他同名工具?您提到的处理异常的方法是正确的吗?然而,这对我们来说不是一个好的选择。我们正在转换大量sql server st