Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 函数在子程序中出现异常后恢复执行_Oracle_Exception_Plsql - Fatal编程技术网

Oracle 函数在子程序中出现异常后恢复执行

Oracle 函数在子程序中出现异常后恢复执行,oracle,exception,plsql,Oracle,Exception,Plsql,我在一个子程序中引发了一个异常,我希望看到调用函数在此时停止执行。然而,调用函数继续处理,就好像什么都没发生一样,我不明白为什么 我的函数如下所示: FUNCTION getFooCursor (i_blah IN VARCHAR) RETURN t_ref_cursor IS v_sum_variable NUMBER; BEGIN --lookup number v_sum_variable := getNumber (i_blah); --cal

我在一个子程序中引发了一个异常,我希望看到调用函数在此时停止执行。然而,调用函数继续处理,就好像什么都没发生一样,我不明白为什么

我的函数如下所示:

FUNCTION getFooCursor (i_blah IN VARCHAR)
    RETURN t_ref_cursor
IS
    v_sum_variable  NUMBER;
BEGIN
    --lookup number
    v_sum_variable := getNumber (i_blah);

    --call function that raises NO_DATA_FOUND exception
    doRaiseException();

    --the exception handler is only supposed to catch for this block
    BEGIN
        --do stuff and end up with a cursor
        RETURN barCursor(v_sum_variable);
    EXCEPTION
        WHEN OTHERS THEN
            --set some variables
    END
END;
PROCEDURE doRaiseException ()
IS
BEGIN
    RAISE NO_DATA_FOUND;
END;
让我们假设
doRaiseException()
如下所示:

FUNCTION getFooCursor (i_blah IN VARCHAR)
    RETURN t_ref_cursor
IS
    v_sum_variable  NUMBER;
BEGIN
    --lookup number
    v_sum_variable := getNumber (i_blah);

    --call function that raises NO_DATA_FOUND exception
    doRaiseException();

    --the exception handler is only supposed to catch for this block
    BEGIN
        --do stuff and end up with a cursor
        RETURN barCursor(v_sum_variable);
    EXCEPTION
        WHEN OTHERS THEN
            --set some variables
    END
END;
PROCEDURE doRaiseException ()
IS
BEGIN
    RAISE NO_DATA_FOUND;
END;
当我在TOAD中调试此函数时,它会很有帮助地通知我已引发NO_DATA_FOUND异常。但是,它会立即执行下一行(调用了
barCursor()
),函数完成时就好像没有出错一样

我尝试过替换
doRaiseException()直接与
生成未找到的数据用于测试目的(它实际上做的不止这些),这会停止
getFooCursor()
中的执行,但无论SQL如何再次调用它,都会完全忽略异常

这就是PL/SQL中异常的工作方式吗?它们不是像Java或C中那样冒泡吗?也许我遗漏了一些关于Oracle中异常的重要信息。我如何获得一个异常以向主机冒泡


这是我的Oracle版本(从v$version返回):


异常按照您的设想工作并“冒泡”,所以您一定在某个地方发现了它

这就是正在发生的事情。。。您正在捕获每个异常,这不是最佳实践。您可以确保只有自己定义了一个。然而,这似乎不是你想在这里做的。您只想重新引发一个异常

所以,你可以在你的子程序中提高它,然后在你的调用块中做类似的事情:

begin
   RaiseException;

exception
   when my_exception_package.my_exception then
      raise;
   when others then
      DoSomethingElse;
end;

这样,您可以捕获要引发的异常,然后重新引发它们。如果异常情况不同,则继续当前的节目流程。

您对异常情况的理解是正确的。然而,对于异常的工作方式来说,这是一个值得注意的例外:在SQL上下文中,找不到任何数据都会被默默地忽略。这是一个“特性”,因为Oracle就是这样告诉其他进程没有更多数据可读取的

对于自定义异常,您可能需要捕获未找到的数据,并将其作为不同的异常引发。这通常是一种处理异常的可怕方法,但这里没有好的替代方法

SQL> create or replace function function1 return number is
  2  begin
  3     raise no_data_found;
  4     return 1;
  5  end;
  6  /

Function created.

SQL> select function1 from dual;

 FUNCTION1
----------


1 row selected.

SQL> create or replace function function2 return number is
  2  begin
  3     raise no_data_found;
  4     return 1;
  5     exception when no_data_found then
  6             raise_application_error(-20000, 'NO_DATA_FOUND raised');
  7  end;
  8  /

Function created.

SQL> select function2 from dual;
select function2 from dual
       *
ERROR at line 1:
ORA-20000: NO_DATA_FOUND raised
ORA-06512: at "JHELLER.FUNCTION2", line 6

你确定你的第一个函数看起来就是这样吗?异常按照您的设想工作并“冒泡”,所以您一定在某个地方捕捉到了它。@Ben:我在我的示例中添加了一些信息,在阅读您的评论后,这些信息突然变得更加相关。回想起来很明显。。。