• oracle 异常处理问题


       最近在写代码的时候遇到异常处理问题,总是弄不太懂,在网上查了一下,大家一起分享。

      

    Pl/sql 提供了一些内建的函数来帮助我们确定、分析异常。

    SQLCODE

    这个函数在前面有提到过,它是一个用于返回当前模块中最近一次异常值的函数,或者说是非入栈程序的异常值。打个比方:如果在当前程序的异常模块中调用了另一个程序, oracle 将当前程序及相应的环境变量(包括异常值)压入系统栈;在被调用程序中生成了一个值为 1 的异常,那么sqlcode 将返回 1 ;之后刚才的程序出栈, sqlcode 返回当前异常值。需要注意的是,不要在异常模块之外使用它,这样不会有任何意义。当没有异常或在异常模块之外使用时, SQLCODE 返回 0 ;返回值 1 是指自定义异常。

    SQLERRM

    接收异常值,返回相应的长度不超过 512 字节的描述语。如果没有传入异常值,则返回当前异常描述。

           Begin

                  Dbms_output.put_line( sqlerrm(-1403);

           End;

    Sql>/

    Ora-1403: no data found

    在需要体构长度超过 512 字节的描述时, oracle 建议使用 dbms_utility.format_error_stack。显然,用这个函数来判断一个异常是否为系统异常是很有用的,如果不是的话,将返回以下两种情况的一种。

    如果是一个负数:

           ora-nnnnn: message not found,; product=rdbms; facility=ora

    如果是一个正数:

           -nnnnn: non-oracle exception

    DBMS_UTILITY.FORMAT_ERROR_STACK

    返回当前异常相应的描述,没有字符长度限制。与 SQLCODE 相同的是,必须在异常处理模块中使用。虽然名称中有一个 stack 在,但通过它并不能知道异常的最初生成处,需要的话就必须使用DBMS_UTILITY.FORMAT_ERROR_BACKTRACE 。

    DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

    系统为最近一次生成的异常设置了一个栈,并跟踪它的传递过程,而这个函数使用这个栈,然后返回该异常的整个传递过程。这个函数对错误的定位和实施下一步处理起着至关重要的作用。

           Create or replace procedure procl is

           Begin

                  Dbms_output.put_line(‘running proc1’);

                  Raise no_data_found;

           End;

           /

           create or replace procedure proc2 is

           begin

                  dbms_output.put_line(‘calling proc1’);

                  proc1;

           end;

           /

           create or replace procedure proc3 is

           begin

                  dbms_output.put_line(‘calling proc2’);

                  proc2;

           exception

                  when no_data_found

                  then

                         dbms_output.put_line(‘error stack at top level’);

                         dbms_output.put_line(dbms_utility.format_error_backtrace);

           end;

           /

    现在可以运行 proc3 来看看结果。

    Sql>set serveroutput on;

    Sql>begin

    2                         dbms_output.put_line(‘proc3->proc2->proc1 backtrace’);

    3                         proc3;

    4     end;

    5     /

        Proc3 -> Proc2 -> Proc1 backtrace

        calling proc2

        calling proc1

        running proc1

        Error stack at top level:

        ORA-06512: at "SCOTT.PROC1", line 4

        ORA-06512: at "SCOTT.PROC2", line 5

    ORA-06512: at "SCOTT.PROC3", line 4

    事实上,每次异常的产生都将重置这个异常栈,只是最后一次从系统栈出栈的是最外层的程序块,所以可以清楚地看到异常生成的整个过程。上面这个程序的执行过程是这样的:首先用 put_line打印 Proc3 -> Proc2 -> Proc1 backtrace , 调用 proc3 ,当前程序入栈 => 打印 calling proc2 ,调用 proc2 , proc3 入栈 => 打印 calling proc1 ,调用 proc1 , proc2 入栈 =>打印 running proc1 ,生成 no_data_found 异常,该异常被压入异常栈中 =>  proc2 出栈,并检测到来自第 5 行调用传递过来的异常,将它在此压入异常栈 => proc3 出栈,并检测到来自第 4 行调用传递过来的异常,将它在此压入异常栈, dbms_utility.format_error_backtrace将异常栈中信息反相打印出来 =>  最外层程序出栈, end 。

    以下是正确使用这个函数的一些注意事项:

    ü         在当前程序的异常处理模块中调用这个函数。

    ü         避免在中间程序中使用异常处理模块。

    这样异常就能被正确地传输到最外层程序中,并打印出这个过程了。

  • 相关阅读:
    将数组扁平化并去除其中重复数据,最终得到一个升序且不重复的数组
    vue 设计一个倒计时秒杀的组件
    es6之三个点(...)扩展运算符
    es6之解构赋值
    es6之字符串添加的东西
    ES6系列之变量声明let const
    js对数组进行删除
    python学习
    泛型
    随笔
  • 原文地址:https://www.cnblogs.com/yangzw478/p/2335701.html
Copyright © 2020-2023  润新知