Home » SQL & PL/SQL » SQL & PL/SQL » Troubleshoot procedure error (Oracle 11g)
Troubleshoot procedure error [message #599366] Wed, 23 October 2013 19:47 Go to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
One of the procedures that am working on is failing with ORA-0000: normal, successful completion error and need some help troubleshooting this issue.

The procedure has got several update and delete statements and have logging enabled after each step. The problem with that again is, each time the log table gets updated thereby losing the history of until what point the procedure ran succesfully.I have this issue only in production environment and unable to simulate it in dev environment which limits my options of troubleshooting the procedure code. I was using SQLERRM in the code still is of no help.

Is there a way I can identify the bad records/ record causing this issue? Am very new to PL/SQL and do not know how to proceed with this.
How do you debug this sort of issues??(where one procedure internally invokes naother one which again invokes other one etc)

Any help is greatly appreciated.

Thanks.
Santhosh
Re: Troubleshoot procedure error [message #599367 is a reply to message #599366] Wed, 23 October 2013 20:33 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
You have table. We don't
You have data. We don't
You have code. We don't
I find it impossible to fix code I can not see.

Since you can not reproduce, what exactly do you expect from here?

what results if you just ignore the ORA-00000?
Re: Troubleshoot procedure error [message #599381 is a reply to message #599366] Thu, 24 October 2013 01:09 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
ORA-0000: normal, successful completion error


As the message says it is not an error.
If you have a look at Error Messages or use oerr tool you can get the meaning of every errors.
ORA-00000: normal, successful completion
 *Cause:  Normal exit.
 *Action: None.
Re: Troubleshoot procedure error [message #599392 is a reply to message #599366] Thu, 24 October 2013 02:53 Go to previous messageGo to next message
ThomasG
Messages: 3211
Registered: April 2005
Location: Heilbronn, Germany
Senior Member
Santhosh05 wrote on Thu, 24 October 2013 02:47
I was using SQLERRM in the code still is of no help.


You weren't using it in some sort of WHEN OTHERS way, were you? Which makes debugging pretty much impossible.
Re: Troubleshoot procedure error [message #599559 is a reply to message #599366] Fri, 25 October 2013 22:18 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
This is the error log that I have:

Oracle::st execute failed: ORA-20001: Job name: STATUS = DONE ERR: COMMENT = Error Happened in processing records ORA-0000: normal, successful completion
ORA-06512: at Check_status_done, line 40
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute) at ./runsql line 89
DBD::Oracle::st execute failed: ORA-20001:Job Name: STATUS = DONE ERR: COMMENT = Error happened in processig records ORA-0000: normal, successful completion
ORA-06512: at "check_status_done", line 40
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute) at ./runsql line 69.

What I was expecting was, how do u usually try to debug a prcoedure which is failing only in Production environment where u don't have any kind of access privileges.
Re: Troubleshoot procedure error [message #599560 is a reply to message #599381] Fri, 25 October 2013 22:20 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
I was getting ORA-0000 error , but not ORA-00000.

Not sure if both refer to the same one, but these are the logs I have from the failed job.

Oracle::st execute failed: ORA-20001: Job name: STATUS = DONE ERR: COMMENT = Error Happened in processing records ORA-0000: normal, successful completion
ORA-06512: at Check_status_done, line 40
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute) at ./runsql line 89
DBD::Oracle::st execute failed: ORA-20001:Job Name: STATUS = DONE ERR: COMMENT = Error happened in processig records ORA-0000: normal, successful completion
ORA-06512: at "check_status_done", line 40
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute) at ./runsql line 89.
Re: Troubleshoot procedure error [message #599561 is a reply to message #599559] Fri, 25 October 2013 22:56 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
Santhosh05 wrote on Fri, 25 October 2013 20:18
This is the error log that I have:

Oracle::st execute failed: ORA-20001: Job name: STATUS = DONE ERR: COMMENT = Error Happened in processing records ORA-0000: normal, successful completion
ORA-06512: at Check_status_done, line 40
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute) at ./runsql line 89
DBD::Oracle::st execute failed: ORA-20001:Job Name: STATUS = DONE ERR: COMMENT = Error happened in processig records ORA-0000: normal, successful completion
ORA-06512: at "check_status_done", line 40
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute) at ./runsql line 69.

What I was expecting was, how do u usually try to debug a prcoedure which is failing only in Production environment where u don't have any kind of access privileges.


It appears to me that what is being run is some sort of PERL code; based upon "DBD::Oracle::st execute failed: ORA-20001:"
In addition Oracle error codes ORA-200XX are user defined; which further obfuscates the actual failure.

I am still in the dark regarding what is actually going wrong or why.

> how do u usually try to debug a prcoedure which is failing only in Production environment where u don't have any kind of access privileges.

Obtain additional privileges or live with the errors.

[Updated on: Fri, 25 October 2013 22:58]

Report message to a moderator

Re: Troubleshoot procedure error [message #599618 is a reply to message #599561] Sat, 26 October 2013 21:35 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
It's not perl code, it's all pl/sql code:

create or replace PROCEDURE proc1 AUTHID current_user AS
       
CURSOR c1 IS
  SELECT DISTINCT col1   as col1_temp
        ,col2  as col2_temp
        ,col3
        ,col4
  FROM  tab1
   WHERE process_dt   IS NULL
     AND col5     = 3 
     AND nvl(col4,'C') <> 'C'
  ORDER by col1_temp, col4
        ;
        
CURSOR c3(v2 INTEGER) IS  
    SELECT distinct col6, col7                                                                                           
    FROM  tab2 WHERE col8 = v2
    ;
    
v1     INTEGER ;
v2   INTEGER ;
v3  INTEGER ; 
v4    INTEGER ; 
v5     INTEGER ; 
                          
v6   INTEGER;
v7 INTEGER;
v8   INTEGER;
v9     INTEGER;
v10 INTEGER;  
error_flag      NUMBER := 0;  /* 0=Normal
                                 1=Abnormal */

v_name        err_log_tbl.name%TYPE := 'Update Order transactions';
v_class       err_log_tbl.class_code%TYPE  := 'ODS';
v_text        err_log_tbl.COMMENT_TEXT%TYPE := null;
v_total       INTEGER := 0 ;

BEGIN

   v_text := 'Program Just Started';
   err_tab(  v_name,'Initial',v_text ,v_class);

FOR c1_rec  IN c1  LOOP

 if c1_rec.col4 = 'I' then

  SELECT col2_temp
  INTO   v2
  FROM   tab3
  WHERE  col3     = c1_rec.col3
  AND    col1_temp = c1_rec.col1_temp
    ;

  v1 := c1_rec.col2_temp;

  UPDATE  tab3
  SET     col2_temp    = c1_rec.col2_temp
  WHERE   col3      = c1_rec.col3
  AND     col1_temp  = c1_rec.col1_temp
    ;
 
  if SQL%rowcount != 1 then
    v_text := 'Error in Updating tab3 record ' || to_char(c1_rec.col1_temp) || '  ' || SQLERRM;
    error_flag := 1;
    exit;
  end if;
    
  pkg1.p1(v2
        ,v1
        ,error_flag
        ,v_text);
      
    IF error_flag > 0 THEN
      exit;
    END IF;                 
    
      
  BEGIN
    v5:= 0;
    
  FOR c3_rec IN c3(v2) LOOP     

    BEGIN
      SELECT  tab2_id 
        INTO  v4
      FROM    tab2  
      WHERE p_id = c3_rec.col6
        AND col2_temp  = v1
      ;
      EXCEPTION when no_data_found then
        v4  := null;
    
    END;        

    IF v4 is not null THEN

      tab2_pkg.del_from_tab2(c3_rec.tab2_id
            ,v4
            ,error_flag
            ,v_text);
  
      if error_flag <> 0 then
        exit;
      end if;         
      
    ELSIF v4 is null THEN

      v6 := tab2_pkg.v6_fac (v1  
                  ,v2  
                  ,c3_rec.tab2_id
                  ,error_flag
                  ,v_text);
                
        IF error_flag <> 0 then
          exit;
        END IF;

      if v6  > 0 then
        
        UPDATE  tab_cl tc
        SET     tab2_ver_id = (SELECT tab2_ver_id
                                 FROM tab2_VER
                                WHERE tab2_id = c3_rec.tab2_id
                                  AND greatest(tc.beg_dt,to_date('12-DEC-99'))
                                        BETWEEN tab2_ver_beg_dt AND tab2_ver_end_dt
                               )
        WHERE  tab2_ver_id in (SELECT tab2_ver_id
                                 FROM tab2_VER
                                WHERE tab2_id = c3_rec.tab2_id
                               )
        ;
    
      end if;   

      tab2_pkg.p1(c3_rec.tab2_id
                ,v2
                ,v1
                ,error_flag
                ,v_text)
                ;
       
        IF error_flag <> 0 then
          exit;
        END IF;
    END IF; /* End of IF v4 is not null */

   
    v5:= v5+ 1 ;

  END LOOP;  
  END ;

    if error_flag <> 0 then
      exit;
    end if;         

  DELETE tab4 WHERE col2_temp = v2;

  DELETE tab6 WHERE col2_temp = v2;
  

  if SQL%rowcount != 1 then
    v_text := 'Error in deleting record ' || to_char(v2) || '  ' || SQLERRM;
    error_flag := 1;
    exit;
  end if;

   UPDATE  tab1
       SET  PROCESS_DT =  trunc(sysdate)
           ,del_col2    = v2
     WHERE col1   = c1_rec.col1_temp
       AND col2       = c1_rec.col2_temp
       AND col3          = c1_rec.col3
       AND col5 = 3
       AND col4       = 'A';

  if SQL%rowcount != 1 then
    v_text := 'Error Found in Update'|| to_char(c1_rec.col1_temp) || '  ' || SQLERRM;
    error_flag := 1;
    exit;
  end if;
  
  elsif c1_rec.col4 = 'R' then 

  UPDATE  tab1
     SET PROCESS_DT =  trunc(sysdate)
   WHERE col1   = c1_rec.col1_temp
     AND col2       = c1_rec.col2_temp
     AND col3          = c1_rec.col3
     AND col5 = 3
     AND col4       = 'R';

 
  if SQL%rowcount != 1 then
    v_text := 'Error Found in Update'|| to_char(c1_rec.col1_temp) || '  ' || SQLERRM;
    error_flag := 1;
    exit;
  end if;

  UPDATE tab6
     SET fac_temp_flag ='N'
   WHERE col2_temp in (SELECT col2_temp
                      FROM tab3
                     WHERE col1_temp = c1_rec.col1_temp
                       AND col3     = c1_rec.col3
                    )
  ;

  end if; 

  if error_flag = 1 then
    exit;
  end if;
  
  v_total := v_total + 1;
  
  IF mod(v_total,100) = 0 then
    v_text  := 'Processed ' || to_char(v_total) || ' succesfully ' ;
    err_tab(v_name ,'Running'  ,substr(v_text,1,120)  ,v_class);
    commit;          
  END IF;   
END LOOP; 

  if error_flag = 0 then
    commit ;
    v_text := 'Complete Processing of ' || to_char(v_total) || ' succesfully ' ;
    err_tab(v_name  ,'Done OK'  ,substr(v_text,1,120)   ,v_class);

  else
    rollback;
    v_text := 'Error Happened' || SQLERRM ;
    err_tab(v_name  ,'Done Err'   ,substr(v_text,1,120)     ,v_class);

  end if;
  
EXCEPTION when OTHERS then 
    rollback;
    v_text := v_text || SQLERRM;
    err_tab(v_name   ,'Done Err'   ,substr(v_text,1,120)   ,v_class);
END;


*BlackSwan corrected {code} tag

[Updated on: Sat, 26 October 2013 21:47] by Moderator

Report message to a moderator

Re: Troubleshoot procedure error [message #599619 is a reply to message #599618] Sat, 26 October 2013 21:52 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>It's not perl code, it's all pl/sql code:
yes, what you posted is PL/SQL
please explain & elaborate as exactly how & why posted code generated posted error log excerpt.
Forgive me, but I doubt that you have ever user PERL (DBI::DBD) to interface with Oracle DB (or any RDBMS)
Simply put, you are mistaken!

>ORA-06512: at "check_status_done", line 40
where in posted PL/SQL does "check_status_done" exist????????????????????????

[Updated on: Sat, 26 October 2013 22:06]

Report message to a moderator

Re: Troubleshoot procedure error [message #599624 is a reply to message #599619] Sat, 26 October 2013 22:45 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
Thank you.

Check status done is generated because of following code:

err_tab(v_name ,'Done Err' ,substr(v_text,1,120) ,v_class);

err_tab is a procedure which updates the process log table in the beginning when the procedure starts and finally updates the table when the procedure finishes to success/failure(done ok/done err).

Re: Troubleshoot procedure error [message #599625 is a reply to message #599624] Sat, 26 October 2013 22:54 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
You will get closer to solving this mystery after you remove, delete, eliminate & omit any and all EXCEPTION handler code including lines below
EXCEPTION when OTHERS then 
    rollback;
    v_text := v_text || SQLERRM;
    err_tab(v_name   ,'Done Err'   ,substr(v_text,1,120)   ,v_class);

at least until after you have corrected what ever bug that throws all the posted errors

[Updated on: Sat, 26 October 2013 23:08]

Report message to a moderator

Re: Troubleshoot procedure error [message #599642 is a reply to message #599619] Sun, 27 October 2013 15:20 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
Of course, the procedure you posted will never throw a runtime error, because:
1) in the WHEN OTHERS block, it does not re RAISE it (as BlackSwan spotted)
2) in the preceding IF statement, it does not raise any exception in the ELSE part (ERROR_FLAG != 0) as well

Most probably, ERROR_FLAG is set to non-zero in one of TAB2_PKG procedures, which are called inside the loop. Then V_TEXT is overwritten in the block mentioned in 2) above with meaningless "Error Happened" and add SQLERRM, which is zero (it is not in exception handler, no error happened until there, it was hidden=not re-raised by one of TAB2_PKG procedures). Removal of that assignment would at least show what the called procedure assigned to it (if its mode is not IN).
By the way, the reported text ( "Error Happened in processing records" ) differs from the text in the code ( "Error Happened" ). Can you explain it?

Good luck in spotting the error in this code which "handles" (hides) errors this way.
Re: Troubleshoot procedure error [message #599643 is a reply to message #599642] Sun, 27 October 2013 15:29 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
BTW - posted code always contains string "Done Err" while posted error log excerpt shows "DONE ERR"
hows does CaSe transformation occur??????
I suspect that you just did a lousy job of obfuscation; since I don't believe posted table names or column names.
Re: Troubleshoot procedure error [message #599644 is a reply to message #599625] Sun, 27 October 2013 17:50 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
The problem is you're treating things as errors when oracle doesn't. eg.
   UPDATE  tab1
       SET  PROCESS_DT =  trunc(sysdate)
           ,del_col2    = v2
     WHERE col1   = c1_rec.col1_temp
       AND col2       = c1_rec.col2_temp
       AND col3          = c1_rec.col3
       AND col5 = 3
       AND col4       = 'A';

  if SQL%rowcount != 1 then
    v_text := 'Error Found in Update'|| to_char(c1_rec.col1_temp) || '  ' || SQLERRM;
    error_flag := 1;
    exit;
  end if;

An update statement that doesn't update 1 row may be an error as far as you're concerned but oracle doesn't see it as an error. So in the case where you end up in that IF statement sqlerrm is "ORA-0000: normal, successful completion".
If oracle had actually thrown an error the code execution would have gone straight to the exception handler.
So all those references to sqlerrm are completely pointless.
Re: Troubleshoot procedure error [message #599864 is a reply to message #599644] Tue, 29 October 2013 10:31 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
Okay thank you all for your responses. What would be a better way of exception handling in order to find the exact location where it's failing with the exact error msg? Finally I've somehow convinced to push the new code with just exception hadling changes to find the exact error msg rather than having to work on something which we are not even sure of. So, would want to know what will be the most efficient way of doing this so that I don't run into same problem with the new code. I've just started working on PL?SQL and a beginner , I can do some reseearch online but I would really appreciate if I could get any kind of info frm u all experts.
Re: Troubleshoot procedure error [message #599866 is a reply to message #599864] Tue, 29 October 2013 10:37 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
Quote:
What would be a better way of exception handling in order to find the exact location where it's failing with the exact error msg?

Do not have ANY exception handling routines. That way, when an actual exception occurs, it will be raised immediately, showing the exact error message and location of where the error occurred.
Now, did you read what CookieMonster wrote? Do you understand what he said?

[Updated on: Tue, 29 October 2013 10:37]

Report message to a moderator

Re: Troubleshoot procedure error [message #599870 is a reply to message #599864] Tue, 29 October 2013 10:51 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
I think you've missed my point. You are getting the exact error message - ORA-0000.
You're getting that message because no error has been raised.
Look at the snippet above - it populates v_text to say there was an error if the update doesn't update exactly 1 row. So say that means it updates 0 rows, that may be a logical problem with your process but it is not an error as far oracle is concerned. So sqlerrm is not going to tell you anything useful.
you need to either:
change the text you write into v_text to actually indicate which update is failing.
or use raise_application_error to have oracle raise an oracle error when an update doesn't do what you want, e.g.

   UPDATE  tab1
       SET  PROCESS_DT =  trunc(sysdate)
           ,del_col2    = v2
     WHERE col1   = c1_rec.col1_temp
       AND col2       = c1_rec.col2_temp
       AND col3          = c1_rec.col3
       AND col5 = 3
       AND col4       = 'A';

  if SQL%rowcount != 1 then
    raise_application_error(-20001, 'update <which one is it> updated '||SQL%rowcount||' rows');
  end if;


Re: Troubleshoot procedure error [message #599888 is a reply to message #599870] Tue, 29 October 2013 18:49 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
Thank you all.
Okay, got what you are saying.
Will it suffice to just modify the v_text indicating where it failed?? Am currently invoking few other packages in the current procedure. If for some reason the code within the invoked package fails, will that be passed to the main procedure?
Found few articles on backtrace, any suggestion which one would be able to take care of the errors within the main program and the errors encountered in the other packages being invoked??
Not having any exception handling code is not option for me.
Re: Troubleshoot procedure error [message #599889 is a reply to message #599888] Tue, 29 October 2013 19:17 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>Not having any exception handling code is not option for me.

Are you referring to where an application business rule is violated or actual Oracle error code & message get thrown?

No explicit EXCEPTION code is an option; but you CHOOSE to pretend this alternative does not exist!



You can lead some folks to knowledge, but you can't make them think.
Re: Troubleshoot procedure error [message #599890 is a reply to message #599888] Tue, 29 October 2013 19:25 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
Santhosh05 wrote on Tue, 29 October 2013 23:49
Thank you all.
Okay, got what you are saying.
Will it suffice to just modify the v_text indicating where it failed??

You tell us, we don't know what you actually want it to do when there is a problem.

Santhosh05 wrote on Tue, 29 October 2013 23:49

Am currently invoking few other packages in the current procedure. If for some reason the code within the invoked package fails, will that be passed to the main procedure?

Are we talking oracle error failure, or doesn't do what you want failure? For the former - yes, unless you have exception handlers preventing it, for the later no unless you specifically code it to do so.

Santhosh05 wrote on Tue, 29 October 2013 23:49

Found few articles on backtrace, any suggestion which one would be able to take care of the errors within the main program and the errors encountered in the other packages being invoked??

What's your definition of taking care of errors?

Santhosh05 wrote on Tue, 29 October 2013 23:49

Not having any exception handling code is not option for me.

It normally is for most people, why do you think you need it?


Generally speaking I only write an exception handler when there is a possibility of an error that shouldn't cause the process to fail (no_data_found being the usual case).
On the other hand if there's a condition that isn't an oracle error, but I want the process to fail anyway, I use raise_application_error
Re: Troubleshoot procedure error [message #599891 is a reply to message #599889] Tue, 29 October 2013 19:30 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
Why do I need to pretend in the first place?

If you/someone else is okay with no exception code , it doesn't mean that everybody would be fine wiht that option.

I apologize but thanks for your efforts of making me think.This is way tooo rude reply for a person who is trying to learn somehting.

Re: Troubleshoot procedure error [message #599892 is a reply to message #599891] Tue, 29 October 2013 19:44 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
Much of this challenge is directly due to previous efforts to "handle exceptions" that have made the situation worse.

The first rule involving holes is as follows:
When you find yourself in a hole, the first thing you should do is to STOP DIGGING!

You insist to continue doing more of the same.
Re: Troubleshoot procedure error [message #599921 is a reply to message #599888] Wed, 30 October 2013 04:10 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
Santhosh05 wrote on Tue, 29 October 2013 23:49

Not having any exception handling code is not option for me.

Why not? The code is not production code yet (is it?) You can remove all exception handling just now, whilst you are developing the code. Once you have the code running correctly, you can then add any exception handling routines that you see fit (raising user defined errors for stuff like updating >1 row, trapping expected exceptions and handling them as needed). The problem at the moment is that your code is a bit of a shambles, therefore one of the quickest things to do is to remove any exception handling that obfuscates the actual issue.
This has already been pointed out to you, but I don't think that you are grasping the significance yet.
if SQL%rowcount != 1 then
    v_text := 'Error in Updating tab3 record ' || to_char(c1_rec.col1_temp) || '  ' || SQLERRM;
    error_flag := 1;
    exit;
  end if;

This is not an exception. As far as Oracle is concerned, all you have done is set the value of a couple of variables. No errors, no exceptions, therefore, as far as Oracle is concerned, the SQLERRM will reflect that in that it will have the error number set to 00000 i.e. "There is no error at the moment"
Look at what cookie posted. that is how should should be handling that situation if, indeed, updating more or less than one row is an error. Actually, I'd probably have two errors there, 1 for 0 rows updated and one for >1 rows updated.

[Updated on: Wed, 30 October 2013 04:10]

Report message to a moderator

Re: Troubleshoot procedure error [message #599948 is a reply to message #599921] Wed, 30 October 2013 06:43 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
This is the code that is failing in Production. And the standards do not allow us to promote any code witout the exception handling added to it.
So the option I was given was to modify he exception handling code to make it better and track whre the error is happening.
Re: Troubleshoot procedure error [message #599949 is a reply to message #599948] Wed, 30 October 2013 06:53 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
So there's another general problem with your error handling.
You have code like this:
  if SQL%rowcount != 1 then
    v_text := 'Error in deleting record ' || to_char(v2) || '  ' || SQLERRM;
    error_flag := 1;
    exit;
  end if;


So if sql%rowcount isn't what you expect you set v_text and error_flag and exit the loop.
Then after the loop you have this:
  if error_flag = 0 then
    commit ;
    v_text := 'Complete Processing of ' || to_char(v_total) || ' succesfully ' ;
    err_tab(v_name  ,'Done OK'  ,substr(v_text,1,120)   ,v_class);

  else
    rollback;
    v_text := 'Error Happened' || SQLERRM ;
    err_tab(v_name  ,'Done Err'   ,substr(v_text,1,120)     ,v_class);

  end if;


And what's that code doing to v_text?
It's overwriting it.
So any information stored in the top code snippet is lost.
And again sqlerrm will be ORA-0000 because no actual oracle error has been encountered.

Your problem here isn't exception handlers, no oracle exceptions are occuring.
Your problems are:
1) you're treating logical application errors as though they are oracle errors when they are not and consequently using sqlerrm in places where it make no sense to do so (anywhere outside of an exception handler)
2) You're not putting any useful information in v_text at any point.
3) you're overwriting v_text.

Personally I'd ditch v_text and use raise_application_error as suggested above.
So the top code snippet something like becomes:
  

  if SQL%rowcount != 1 then
    raise_application_error(-20001, Error in deleting record ' || to_char(v2) || <some other useful info for logging>);
  end if;


Raising an actual oracle error will cause code execution to jump straight to the exception handler, so you don't need error_flag or an exit and the 2nd code snippet simply becomes:
    commit ;
    v_text := 'Complete Processing of ' || to_char(v_total) || ' succesfully ' ;
    err_tab(v_name  ,'Done OK'  ,substr(v_text,1,120)   ,v_class);


The exception handler will work as is assuming that the caller of the procedure doesn't need the exception raised up to it (which isn't normally the case).
I suggest you have a read of this thread on asktom: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1155066278457 plus others on there about exception handling (just type "exception when others" into the search box on the main page.
Re: Troubleshoot procedure error [message #599952 is a reply to message #599948] Wed, 30 October 2013 07:06 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
Santhosh05 wrote on Wed, 30 October 2013 11:43
This is the code that is failing in Production.
OK, but you're not fixing it in production are you? You presumably take the procedure into UAT and work on it in there, yes?
Quote:
And the standards do not allow us to promote any code witout the exception handling added to it.
Please read what I wrote again.
Quote:
So the option I was given was to modify he exception handling code to make it better and track whre the error is happening.
Removing it alltogether would make it better quite frankly.
As for the rest of the issues, there's is little point in me repeating what CookieMonster has already said (more than once).
Re: Troubleshoot procedure error [message #599956 is a reply to message #599366] Wed, 30 October 2013 07:26 Go to previous messageGo to next message
Santhosh05
Messages: 13
Registered: March 2010
Location: US
Junior Member
Spot on. That's what I mentioned in my initial post:the log msgs are getting overwritten thereby losing track of where exactly the error happened.
So I'll go ahead and modify the application related errors like sql%rowcount>1 etc to use raise_application_error.
And are you suggesting me to get rid of the else part of error_flag=0(below),since if there was an oracle error it will be taken care by the exception when others section??


if error_flag = 0 then
    commit ;
    v_text := 'Complete Processing of ' || to_char(v_total) || ' succesfully ' ;
    err_tab(v_name  ,'Done OK'  ,substr(v_text,1,120)   ,v_class);

  else
    rollback;
    v_text := 'Error Happened' || SQLERRM ;
    err_tab(v_name  ,'Done Err'   ,substr(v_text,1,120)     ,v_class);

  end if;



Also, I was invoking other packages from this main procedure. And I have exception when others code there in too. DO I really have to exception handling within these packages as well, since I have exception handlers in my main program??

Ex:Iwas invoking the following package from my main program


tab2_pkg.del_from_tab2(c3_rec.tab2_id
            ,v4
            ,error_flag
            ,v_text);



And the tab2_pkg.p1 code is as follows:

Procedure proc_name(params)

Begin

Update statements

exception when others then
v_text := Error while update on Prov for Facility ' || to_char(from_prov_id)|| ' : '||SQLERRM;
error_flag :=1 ;

end;


Based on what you said, I would imagine if there is an Oracle error in this package tht got called/invoked, it jumps to the exception handling section of main program . So don't have to use it and just can raise_application_error if am getting unexpected count(sql%rowcount>1).

Thanks for the detailed explanation.



Re: Troubleshoot procedure error [message #599959 is a reply to message #599956] Wed, 30 October 2013 07:44 Go to previous message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
Santhosh05 wrote on Wed, 30 October 2013 12:26

And are you suggesting me to get rid of the else part of error_flag=0(below),since if there was an oracle error it will be taken care by the exception when others section??

yes

Santhosh05 wrote on Wed, 30 October 2013 12:26

Also, I was invoking other packages from this main procedure. And I have exception when others code there in too. DO I really have to exception handling within these packages as well, since I have exception handlers in my main program??

.....

Based on what you said, I would imagine if there is an Oracle error in this package tht got called/invoked, it jumps to the exception handling section of main program . So don't have to use it and just can raise_application_error if am getting unexpected count(sql%rowcount>1).



Pretty much, though once you look at other procedures you need to check they're not called by other things apart from your main procedure.
Because a procedure ending in error vs a procedure swollowing all errors and passing back a parameter obviously effects how it interacts with it's callers.

Have a look at the asktom threads for discussions on statement level atomicity - it's very relevant.
Previous Topic: update with case using select
Next Topic: Can we have 2 insert statements for 1 for loop
Goto Forum:
  


Current Time: Fri Apr 26 01:33:34 CDT 2024