Question : Handling Exceptions and Grabbing Oracle error messages

Hi Guys,

Given a script below:

ScriptName : InsRecOnMytable.sql
--------------------------------



DECLARE
ERR_MSG         VARCHAR2(4000);
SCRT_NAME       VARCHAR2(400) := 'InsRecOnMytable.sql';


BEGIN

  Insert into myschema.mytable (SCHEMA,NAME,REMARK,ORACLE_TYPE,FUNCTIONAL_TYPE,OWNER,DETAIL_OWNER,IS_DYNAMIC,DISPLAY_NAME,ENTITY_NAME)
     values ('myschema','mytable',' sample table 1','TABLE','BASIC','PRODUCT','PRODUCT',0,'Sample 1',null);

  Insert into myschema.mytable (SCHEMA,NAME,REMARK,ORACLE_TYPE,FUNCTIONAL_TYPE,OWNER,DETAIL_OWNER,IS_DYNAMIC,DISPLAY_NAME,ENTITY_NAME)
     values ('myschema','mytable',' sample table 2','TABLE','BASIC1','PRODUCT1','PRODUCT1',1,'Sample 2',null);

  commit;
 
  GrabErr(SCRT_NAME, 'Success');

END IF;

EXCEPTION
   WHEN DUP_VAL_ON_INDEX THEN  -- handles duplicate records error
     
       select <ORA-00001 msg resulted from the duplicate insert above> into ERR_MSG from dual;

       GrabErr(SCRT_NAME, ERR_MSG); -- a procedure that takes the ERR_MSG as parameter
 
   WHEN OTHERS THEN  -- handles all other errors
       
       select <ORA-00001 msg resulted from the duplicate insert above> into ERR_MSG from dual;

       GrabErr(SCRT_NAME, ERR_MSG); -- a procedure that takes the ERR_MSG as parameter
   
       ROLLBACK;
END;
/

I just need a way to be able to pass or store using a variable the actual ORACLE error message resulted from duplicate record above and more importantly, the line number where the error occured for debugging purposes.

the script above is an idea only. Feel free to suggest whatever is the best solution via PL/SQL.

Using LOG file will work but the idea here is that the GrabErr procedure will update some columns on a table say  SCRIPTINFO containing the details for each script being executed. If there's a way to create the LOG file and at the same time be able still to update SCRIPTINFO table, then so much better.


Something like this:
--------------------


SCRIPTINFO TABLE
----------------

ID        NAME                            EXEC_STATUS      REMARKS
===========================================================================
1         InsRecOnMytable.sql              FAILED                  <actual oracle err msg.>
2         MyScriptInsert.sql                   OK                         Success
===========================================================================


Can something like this be done?

Thanks in advance,
jrmn

Answer : Handling Exceptions and Grabbing Oracle error messages

Your code is OK, but I would recommend some changes:

There is no need of doing this:
select <ORA-00001 msg resulted from the duplicate insert above> into ERR_MSG from dual;
The error is in these variables:SQLCODE and SQLERRM, so

EXCEPTION
   WHEN DUP_VAL_ON_INDEX THEN  -- handles duplicate records error

       GrabErr(SCRT_NAME, SQLCODE||' '||SQLERRM);
      ROLLBACK;   -- I have added this because in a procedure GrabErr there ought to be AUTONOMOUS TRANSACTION

   WHEN OTHERS THEN  -- handles all other errors
       
       GrabErr(SCRT_NAME, SQLCODE||' '||SQLERRM);
   
       ROLLBACK;
END;

In the procedure GrabErr use AUTONOMOUS TRANSACTION.
You can also define your own application errors.
Here is more about exception handling:
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/errors.htm#i7014

If you want to know the line where error occurs then add a variable e.g. n_debug:

DECLARE
SCRT_NAME       VARCHAR2(400) := 'InsRecOnMytable.sql';
    n_debug  PLS_INTEGER:=0;

BEGIN
    n_debug :=1;
  Insert into myschema.mytable (SCHEMA,NAME,REMARK,ORACLE_TYPE,FUNCTIONAL_TYPE,OWNER,DETAIL_OWNER,IS_DYNAMIC,DISPLAY_NAME,ENTITY_NAME)
     values ('myschema','mytable',' sample table 1','TABLE','BASIC','PRODUCT','PRODUCT',0,'Sample 1',null);

    n_debug :=2;

  Insert into myschema.mytable (SCHEMA,NAME,REMARK,ORACLE_TYPE,FUNCTIONAL_TYPE,OWNER,DETAIL_OWNER,IS_DYNAMIC,DISPLAY_NAME,ENTITY_NAME)
     values ('myschema','mytable',' sample table 2','TABLE','BASIC1','PRODUCT1','PRODUCT1',1,'Sample 2',null);

    n_debug :=3;
  commit;

 
  GrabErr(n_debug,SCRT_NAME, 'Success');

END IF;

EXCEPTION
        GrabErr(n_debug,SCRT_NAME, SQLCODE||' '||SQLERRM);
       ROLLBACK;

   WHEN OTHERS THEN  -- handles all other errors
       
       GrabErr(n_debug,SCRT_NAME, SQLCODE||' '||SQLERRM);
   
       ROLLBACK;
END;

I do it this way. You can also create a procedure with input parameter SCRT_NAME and instead of script you can use the procedure.

I hope this will be a little help for you.
Random Solutions  
 
programming4us programming4us