kalls
kalls

Reputation: 2855

Existing state of package discarded - Oracle

I am using Oracle and I have modified code on some triggers and a package. When I run the script file which modifies the code and try to do an update on a table (which fires the trigger) I am getting Existing State of Package discarded

I am getting a bunch of error

ORA-04068:
ORA-04061:
ORA-04065:
ORA-06512:--Trigger error -- line 50
ORA-04088:

This error is happening only the first time. Any inputs to avoid this would be greatly appreciated. Thank you!

Upvotes: 3

Views: 4406

Answers (3)

Oly
Oly

Reputation: 1

I had the same problem.

My situation was that I wrote a dynamic creation script for a package, then in the next script line call the procedure from the package. I think you're in the same situation.

The problem I detected was that the timestamp for the package generation was identical to the timestamp of the procedure call. Nowadays, with faster and faster servers ... it happens.

So in the generation script I have introduced dbms_lock.wait(2) after the package creation line.

This got rid of the problem!

Upvotes: 0

Tony BenBrahim
Tony BenBrahim

Reputation: 7290

serially_reusable only makes sense for constant package variables.

There is only one way to avoid this error and maintain performance (reset_package is really not a good option). Avoid any package level variables in your PL/SQL packages. Your Oracle's server memory is not the right place to store state.

If something really does not change, is expensive to compute and a return value from a function can be reused over and over without recomputation, then DETERMINISTIC helps in that regard

example: DON'T DO THIS: varchar2(100) cached_result;

function foo return varchar2 is
begin
  if cached_result is null then
     cached_result:= ... --expensive calc here
  end if; 
 return cached_result;
end foo;

DO THIS INSTEAD

function foo return varchar2 DETERMINISTIC is
begin
  result:=... --expensive calc here
  return result;
end foo;

Deterministic tells Oracle that for a given input, the result does not change, so it can cache the result and avoid calling the function.

If this is not your use case and you need to share a variable across sessions, use a table, and query it. Your table will end up in the buffer cache memory if it is used with any frequency, so you get the in memory storage you desire without the problems of session variables

Upvotes: 6

Joel Slowik
Joel Slowik

Reputation: 653

Your script is more than likely caching out-dated code. So, from Michael Pakhanstovs link you can run

DBMS_SESSION.RESET_PACKAGE 

at the beginning of your script or use

PRAGMA SERIALLY_REUSABLE; 

in your script.

Note however the implications of both:

http://download.oracle.com/docs/cd/B13789_01/appdev.101/b10807/13_elems046.htm

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sessio.htm#i1010767

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2298325131459

AskTom on DBMS_SESSION.RESET_PACKAGE:

dbms_session.reset_package, while MUCH faster then logging in and out, has some performance implications (not as fast as not doing it obviously!). That and it'll rip down the entire session state, eg: any opened cursors you have (prepared statements) as well.

AskTom on PRAGMA SERIALLY_REUSABLE:

Its basically saying 'if you use a package and you don't save a state in that package and would like avoid having the persistance of the package in your session -- less memory -- use this'

Upvotes: 3

Related Questions