在oracle中的存储过程中,使用的EXCEPTION并用WHEN OTHERS THEN进行捕获,但是捕获了后就没有办法知道出错具体出在哪一行,无法更正是哪一行报出的异常,是否有好的解决方法。

解决方案 »

  1.   

    你调试呗!用PL/SQL debug
      

  2.   

    1、用PL/SQL里面选择TEST->F9(开始测试)->打断点->选择执行到下一断点处。
    2、使用DBMS_OUTPUT.PUT_LINE();每个SQL后面都加一个,结束后看看打印到那个就没了,对应的那个    SQL就是出问题的地方。我通常写存储过程都用同一个EXCEPTION
    EXCEPTION
     WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE(SQLERRM);
       P_ERR_LOG(SQLERRM,'PROCEDURE_NAME',SYSDATE);
       ROLLBACK;P_ERR_LOG是个存储过程,参数按顺序为:
    错误信息、出错过程名称、时间
    然后把信息存入一张日志表中。
      

  3.   

    EXCEPTION
        WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);
            DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_CALL_STACK);这样就能把错误的详细信息打印出来了
      

  4.   

    可以定义一个变量stmt_no,在每句前面为此变量赋值,如果出现exception,则stmt_no就是对应值的下一句,下面是Oracle给出的例子:CREATE OR REPLACE PROCEDURE loc_var AS
       stmt_no NUMBER;
       name    VARCHAR2(100);
    BEGIN
       stmt_no := 1;  -- designates 1st SELECT statement
       SELECT table_name INTO name
         FROM user_tables
         WHERE table_name LIKE 'ABC%';
       stmt_no := 2;  -- designates 2nd SELECT statement
       SELECT table_name INTO name
         FROM user_tables
         WHERE table_name LIKE 'XYZ%';
    EXCEPTION
       WHEN NO_DATA_FOUND THEN
          DBMS_OUTPUT.PUT_LINE
            ('Table name not found in query ' || stmt_no);
    END;
    /
    CALL loc_var();
      

  5.   

    只能如4楼所说了,这是oracle比sql server愚蠢的地方之一
      

  6.   

    #4的做法是客户的1997版代码标准;还有一种是尽量把逻辑写细到一个个小的procedure,然后用一个main procedure在包内调用,每次调用后将计数器加1,然后将该数字保存到一个专门的表中,知道最后一步成功后再将计数器置1,这样也容易知道错误位置,再次运行时可以从错误位置直接启动,restartbility非常好。这种写法是目前客户公司的2008版的代码标准。