I have a script that makes use of a package (PKG_MY_PACKAGE). I will change some of the fields in a query in that package and then recompile it (I don’t change or compile any other packages). I run the script and I get an error that looks like
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "USER3.PKG_MY_PACKAGE" has been invalidated
ORA-04065: not executed, altered or dropped package body "USER3.PKG_MY_PACKAGE"
ORA-06508: PL/SQL: could not find program unit being called: "USER3.PKG_MY_PACKAGE"
ORA-06512: at line 34
I run the script again (without changing anything else in the system) and the script executes successfully.
I thought that when I compiled before I executed the script that would fix any invalid references. This is 100% reproducible, and the more I use this script the more annoying it gets. What could cause this, and what would fix it?
(oracle 10g, using PL/SQL Developer 7)
Background
existing state of packages has been discardedmeans, that your Package (or Body) had some sort of state, which was lost by a recompilation.This is caused by a global variable stored in your Package.
Until 11.2.0.2, constants did also cause this behavior (see documentation).
Since the package had already been used in your session, Oracle assumes that this state is relevant for you. Some variables might have changed, and when you recompile, the values are reset.
This exception is thrown, so that your clients know that they can’t rely on those variables any more.
Solutions
Solutions (changing source)
DETERMINISTICfunctions (as suggested by this answer)PRAGMA SERIALLY_REUSABLEcauses Oracle to re-initialize the global variables with every call to the server.