技术开发 频道

Oracle PL/SQL语言的异常处理

    当异常抛出后,控制无条件转到异常部分,这就意味着控制不能回到异常发生的位置,当异常被处理和解决后,控制返回到上一层执行部分的下一条语句。

BEGIN DECLARE bad_credit; BEGIN RAISE bad_credit; --发生异常,控制转向; EXCEPTION WHEN bad_credit THEN dbms_output.put_line('bad_credit'); END; --bad_credit异常处理后,控制转到这里 EXCEPTION WHEN OTHERS THEN --控制不会从bad_credit异常转到这里 --因为bad_credit已被处理 END;

    当异常发生时,在块的内部没有该异常处理器时,控制将转到或传播到上一层块的异常处理部分。

BEGIN DECLARE ---内部块开始 bad_credit; BEGIN RAISE bad_credit; --发生异常,控制转向; EXCEPTION WHEN ZERO_DIVIDE THEN --不能处理bad_credite异常 dbms_output.put_line('divide by zero error'); END --结束内部块

    --控制不能到达这里,因为异常没有解决;
    --异常部分

    EXCEPTION
    WHEN OTHERS THEN
    --由于bad_credit没有解决,控制将转到这里
    END;

    异常传播

    没有处理的异常将沿检测异常调用程序传播到外面,当异常被处理并解决或到达程序最外层传播停止。
    在声明部分抛出的异常将控制转到上一层的异常部分。

BEGIN executable statements BEGIN today DATE:='SYADATE'; --ERRROR BEGIN --内部块开始 dbms_output.put_line('this line will not execute'); EXCEPTION WHEN OTHERS THEN --异常不会在这里处理 END;--内部块结束 EXCEPTION WHEN OTHERS THEN 处理异常 END

    执行部分抛出的异常将首先传递到同一块的异常部分,如果在同一块的异常部分没有处理这个异常的处理器,那么异常将会传播到上一层的异常部分中,一直到最外层。

    在异常部分抛出的异常将控制转到上一层的异常部分。

    处理异常将停止异常的传播和解决。有时用户希望在错误发生时,程序仍然能执行一些动作,要达到这个目的,可以把希望执行的动作放在异常处理器中,然后执行不带参数的RAISE语句,RAISE语句将重新抛出出现的异常,允许他继续传播。

DECLARE order_too_old EXCEPTION; BEGIN RAISE order_too_old; EXCEPTION WHEN order_too_old THEN DECLARE file_handle UTL_FILE.FILE_TYPE; BEGIN --open file file_handle:=UTL_FILE.FOPEN (location=>'/ora01/app/oracle/admin/test/utlsir' ,filename=>'error.log' .open_mode=>'W'); --write error stack UTL_FILE.PUT_LINE(filehandle, DBMS_UTILITY.FORMAT_ERROR_STACK); --write the call stack UTL_FILE.PUT_LINE(filehandle, DBMS_UTILITY.FORMAT_CALL_STACK); --close error log UTL_FILE.FCLOSE(file_handle); RAISE; --re-raise the exception END END

    如果从FORMAT_XXX_STACK输出一个很大的值,那么使用DBMS_OUTPUT或UTL_FILE显示错误或调用堆的异常部分自身也会抛出异常,这两个堆常规下最多能返回2000字节,但utl_file.put_line被限制在1000字节以内,而dbms_output.put_line限制在512字节内。如果使用前面的代码并且不允许这种可能性,那么在异常处理器中将抛出一个未处理的异常。

    GOTO语句不能用于将控制从执行部分传递到异常部分或反之。
   

0
相关文章