ITPub博客

首页 > Linux操作系统 > Linux操作系统 > How to Handle ORA-4068

How to Handle ORA-4068

原创 Linux操作系统 作者:hexiaomail 时间:2010-07-02 11:05:14 0 删除 编辑

Applies to:

PL/SQL - Version: 10.2.0.4
Information in this document applies to any platform.

Goal

How to handle this errors in PLSQL?
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "user.package" has been invalidated
ORA-04065: not executed, altered or dropped package "user.package"
ORA-06508: PL/SQL: could not find program unit being called: "user.package"
ORA-06512: at line 7

The idea is to catch this error and then to call again the package because the second time the package is reinstantiated. But it seems not possible.

Solution

The point of trapping these errors is usually so you can tidy up before resetting and continuing. However you have to then return back to the client (ie the caller) with the error in order for the new package state to be picked up and to allow you to then continue. You can't just trap the error and continue in the same plsql call as though nothing has happened.

To trap the error you need to trap the ora-6508 in this case.

Code for session 1 looks like:
declare
  package_exception exception;
  PRAGMA EXCEPTION_INIT (package_exception, -6508);
  d pls_integer;
begin
  d:=package.function;
  dbms_output.PUT_LINE(d);
  dbms_lock.sleep(10); --> to allow me time to recreate package
exception
  when package_exception then
  dbms_output.put_line('Called failed with '||sqlcode);
end;
/

and run it 3 times, do 'alter package ... compile;' in a second session
while it is running the first time, then this is the output:

0
PL/SQL procedure successfully completed.

Called failed with -6508
PL/SQL procedure successfully completed.

Called failed with -6508
PL/SQL procedure successfully completed.


So the first call worked. The second failed but so did the third because the error is not raised back to the client in order for it to reset. When the exception handler is changed to have a "raise;" after the dbms_output then this is the output:

declare
  package_exception exception;
  PRAGMA EXCEPTION_INIT (package_exception, -6508);
  d pls_integer;
begin
  d:=test_pkg111.getInfo111;
  dbms_output.PUT_LINE(d);
  dbms_lock.sleep(10); --> to allow me time to recreate package
exception
  when package_exception then
  dbms_output.put_line('Called failed with '||sqlcode);
  raise;
end;
/

0
PL/SQL procedure successfully completed.

declare
*
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "user.package" has been invalidated
ORA-04065: not executed, altered or dropped package "user.package"
ORA-06508: PL/SQL: could not find program unit being called: "user.package"
ORA-06512: at line 12


PL/SQL procedure successfully completed.

ie first and third calls worked. Note to see the output for the third run you need to turn serveroutput on again as the whole session state has been reset after the failed second call which is why you don't see the output from this either.

This demonstrates how it works / is supposed to work.

You can trap to clean up but you must raise the error back to your caller (ie come out of plsql completely) for it to handle the error and reset the session state allowing you to continue.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9932141/viewspace-666931/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-07-05

  • 博文量
    86
  • 访问量
    219970