Skip to Main Content
  • Questions
  • Problems with forms or libraries that reference a recompiled package spec

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Gustavo.

Asked: October 24, 2000 - 9:32 am UTC

Last updated: June 23, 2005 - 6:22 pm UTC

Version: 2.1

Viewed 1000+ times

You Asked

I read the article about automatic compiling published on September/october 2000 in Oracle Magazine.
We work over Oracle 7.3 and developer 2.1 and we have the following problem :sometimes when we compile a package specification (for example we only change the parameter type from number to char) the forms and libraries that reference that package will show the message ORA-04068 "existing state of packages has been discarded" if the forms or libraries are not recompiled.
Are there any settings I could use in the Oracle Database or Developer/2000, or patches I could use in order to compile the package without having to recompile the forms or libraries ?

Thank You

and Tom said...

Well, if you change the SPECIFICATION (changing the datatype from number to char for example) will necessarily force the recompilation of dependent code! You've totally changed what the calling is calling -- forms needs to rebuild its dependent code to now cast a number into a character string before calling the procedure.


Specs should never change in production and when they do -- you need to recompile all dependent objects. The only solution short of that would be to use dynamic sql to invoke everything and do all of the binding yourself (at which point you still have a problem -- you would be binding a number to a string which might work for IN but probably won't work for IN OUT variables).

It is like it would be if you were programming in C or Java and suddenly changed a subroutine from taking an "int" as a parameter to taking a "char *" -- all code that calls that must be recompiled and relinked after changing the datatypes being passed. PLSQL will automatically cast the type for us but it must be recompiled to do so..

Rating

  (21 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, July 26, 2002 - 6:10 pm UTC

Hi Tom,
We are running into the same error (ORA-04068: existing state of packages has been discarded), but we didn't change the specification, we only recreate the package body.
Every time when a developer recreate a package body,
all the dependent object run into this problem the first time when an application tries to execute the dependent object after the change, and if you go to the dba_objects the dependent object is valid.
We also run into this problem with remote dependent object, but in this case if you check the dba_objects for the remote dependent object you can see that the object is invalid.
Is there any way to avoid this error and the cancelation of the execution? Is there any way to let the applications to recompile the dependent object without aborting the execution?

Thanks

Tom Kyte
July 28, 2002 - 3:21 pm UTC

You changed the package body -- they have a state as well. You changed the code people were running, they MUST get this message and then they can "start over". You've trashed their state, plain and simple.


The STATE of the package body you just recompiled -- gone, wiped out, must be re-established (and imagine the bugs if we DID'T raise this error???)



A reader, July 28, 2002 - 10:57 pm UTC

Thanks Tom,

I understood what you said.
But I have a two more questions:

1-why the dependent objects are still valid in the dba_objects after we change the package? Shouldn't they be invalid too? because in the case of remote dependent object if you go to the dba_object (in the remote database) you will find that the dependent object will be invalid.

2-how does exactly work the remote_dependent_mode parameter? I will really appreciate if you can explain me both alternatives timestamp and signature. I read the oracle documentation but it wasn't very clear to me.

Thanks

Tom Kyte
July 29, 2002 - 7:08 am UTC

1) the objects are dependent on the SPEC, not the body. You did not change what they are dependent on so -- no, they should not be invalidated (it is one of the major advantages of packages that they are not)

2) with timestamp, if the timestamp in the remote data dictionary changed (the package was compiled for any reason and the data dictionary reflects that) -- the package that is dependent on the remote code will go invalid AT THE POINT IN TIME it first references the remote code.

In "signature" mode, we will remember not the timestamp but rather the name of the remote object, the number types and names of the inputs/outputs and the return value type if any. That is the signature of the object. If that changes -- then the local object will go invalid at the point in time it first references the remote code.

A reader, July 29, 2002 - 1:30 pm UTC

Hi Tom,

If I understood well, if I only recreate the specification (in my case i didn't change anything in the code, i only recreate it) and the body wasn't changed, the remote dependent object should not either receive any error or get invalid when it is execute.

I was doing some tests and taking into account what you said, I still don't understand why I am receiving the error, 
ORA-04068: existing state of packages has been discarded
ORA-04062: timestamp of package "SCOTT.PKG_A" has been changed


Here is my test:

I have a package (named pkg_A) in database A and a function (named funct_B) in database B which calls pkg_a through a dblink. 
Every time when a recreate the specification (I don't change anything I just recreated it) I receive the the error 4068 and 4062.

Databas A and B has the remote_dependent_object=signature

Database A: Before the change
----------

SQL>select * from dba_objects where object_name='PKG_A' and owner='SCOTT';

OWNER
------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED   LAST_DDL_ TIMESTAMP           STATUS  T G S
--------- --------- ------------------- ------- - - -
SCOTT
PKG_A
                                    41071                PACKAGE
24-JUL-02 26-JUL-02 2002-07-26:15:28:22 VALID   N N N

SCOTT
PKG_A
                                    41072                PACKAGE BODY
24-JUL-02 26-JUL-02 2002-07-26:15:54:53 VALID   N N N

Database B: before the change
----------

SQL>select * from dba_objects where object_name='FUNCT_B');

OWNER
------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED   LAST_DDL_ TIMESTAMP           STATUS  T G S
--------- --------- ------------------- ------- - - -
TIGER
FUNCT_B
                                    36359                FUNCTION
24-JUL-02 26-JUL-02 2002-07-26:16:18:03 VALID   N N N


After I recreated the package specification, the status is the following:

Database A: after the change
-----------

OWNER
------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED   LAST_DDL_ TIMESTAMP           STATUS  T G S
--------- --------- ------------------- ------- - - -
SCOTT
PKG_A
                                    41071                PACKAGE
24-JUL-02 29-JUL-02 2002-07-29:11:11:56 VALID   N N N

SCOTT
PKG_A
                                    41072                PACKAGE BODY
24-JUL-02 29-JUL-02 2002-07-29:11:10:30 INVALID N N N


SQL_>alter package scott.PKG_A compile body;

Package body altered.



SCOTT
PKG_A
                                    41071                PACKAGE
24-JUL-02 29-JUL-02 2002-07-29:11:11:56 VALID   N N N

SCOTT
PKG_A
                                    41072                PACKAGE BODY
24-JUL-02 29-JUL-02 2002-07-29:11:12:06 VALID   N N N




Database B: after the change (including the recompilation of the body)
-----------

SQL>select tiger.FUNCT_B from dual;
select tiger.FUNCT_B from dual
       *
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "SCOTT.PKG_A" has been invalidated
ORA-04065: not executed, altered or dropped package "SCOTT.PKG_A"
ORA-06512: at "TIGER.FUNCT_B", line 4
ORA-06512: at line 1


OWNER
------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
------------------------------ ---------- -------------- ------------------
CREATED   LAST_DDL_ TIMESTAMP           STATUS  T G S
--------- --------- ------------------- ------- - - -
TIGER
FUNCT_B
                                    36359                FUNCTION
24-JUL-02 26-JUL-02 2002-07-26:16:18:03 INVALID N N N

Thanks for taking time to explain this to me. I really appreciated.
 

Tom Kyte
July 29, 2002 - 2:01 pm UTC

Yes, you trashed the state -- the package state. We don't care about timestamp/signature here, this is the STATE you are talking about. You wiped out the package state.

The timestamp/signature argument only applies to the initial invocation -- the caller will look at the callee and say "do I need to recompile myself, did this change since I've last looked? No -- Ok, continue"

You got page that point, trashed the state and tried to run it again. Doesn't matter timestamp or signature -- you trashed the state.

A reader, July 29, 2002 - 5:38 pm UTC

Hi Tom,

Thanks now I understand better.

When you say "you trashed the state", what do you exactly mean? How do you define the "state" of an object?

thanks again

Tom Kyte
July 29, 2002 - 7:45 pm UTC

the state is the settings of any and all global variables -- the "state" of the package. You "trashed" it -- eg: wiped it out -- by replacing it.

Problems with forms or libraries that reference a recompiled package spec

Hohenthal, August 05, 2002 - 1:00 am UTC

If application should be running all the time, then it is very difficult to find time to bring new versions of package bodies, because of this 'existing state of package has been discarded'. Actually many packages don't have this 'package state', what is meaningfull for application. They may use global variables for caching or they may even have this restrict references pragmas RNPS, WNPS. If they have RNPS,WNPS pragmas it would be very usefull, if oracle would automatically flush this package and use new version. Maybe some cursors should be reopened automatically. Other possibility would be some kind of 'statesless' pragma (like this new deterministic) stating that application programmer is taking responsibility of this 'existing state of package has discarded problem' when new version of package body is brought into database.

Tom Kyte
August 05, 2002 - 11:36 am UTC

do you understand that if we just flushed these packages -- wiping out the state -- it would be a very very bad thing. It would lead to horrible bugs (a state is something you need to be ABLE TO COUNT ON BEING THERE!!!!!!)

There is a stateless pragma -- serially_reusable. It may be useful in your case. However, you won't be using globals (a state) for ANYTHING -- ever.



Problems with forms or libraries that reference a recompiled package spec

Hohenthal, Helsinki, August 06, 2002 - 8:41 am UTC

I have in mind applications that are using transaction monitors or application servers and should be working 7 * 24. If they are calling package (pack_a) that is further calling some other package (pack_b) then replacing body of package pack_b can cause this 'existing state of package has been ...'. However this package may not even use global variables (restrict_references is WNPS, RNPS) and application programmer knows that this package does not assume that cursors are open or anything like that.
(I do agree that flushing the state of package can be dangerous, but to many applications it doesn't matter. Most procedures and functions are actually used in stateless fashion (e.g routine fetching name of customer)).

I have not used this serially_reusable pragma, but does it solve this problem ? It would be very usefull, that those wanted package bodies could be replaced on the fly.

Tom Kyte
August 07, 2002 - 9:32 am UTC

Tell me, in this 24x7 environment -- when you have to update your C code that is in the TPM, what do you do then (hey, you shutdown since you cannot replace C code which is being used). The SAME exact issue is arising here. The same exact issue.

Did you read about it (serially reusable)?????

I can only lead you so far -- after that you must investigate this yourself.

</code> http://docs.oracle.com/docs/cd/A87860_01/doc/appdev.817/a77069/05_ora.htm#36195 <code>

It effectively takes away the "statefullness" of the package.

(also, in a TPM environment - i don't see how you would be hitting this "existing state" error since a TPM by its very definition is "single message in -- do a single transaction -- and get the heck out of there". There is no long running session with multiple calls to and from the database).

A reader, December 26, 2002 - 3:11 pm UTC

Tom,

I have a package (pkg_a) on database A and a function (func_X) on database B which calls pkg_a through a db link.
Database A and B has the remote_dependencies_mode=SIGNATURE.
If I change the package specification (say I added a new procedure in the body so I need to add that procedure in the specification) the first time when I call the function (func_x) on database B the function runs OK, it doesn't get invalid.
I tested this calling the function in a new sql session and also in another sql session which was using the function (func_x) before I made the changes in the package specification. In both cases the function run ok and it didn't get invalid at any time.
Shouldn't the function (func_x) on database B get invalid when I run it after recompile the package specification in database A?

Thanks for your help.

Tom Kyte
December 26, 2002 - 3:24 pm UTC

only if the signature of the called function / procedure changes -- which it didn't. you added a new procedure, you didn't touch the old ones.

A reader, December 26, 2002 - 4:45 pm UTC

Tom,
Thanks for answering me, I understand your point.
But I have another question, I have another example using the same package (pkg_a) and funtion (func_x) but now I added a new function in database B called func_y. This new function called another procedure which is also inside pkg_a but this procedure is different from the one called by func_x.
If I change the name of the procedure called by func_x in the package (body and specification) and then I run func_y everything is ok, func_y runs without problems and both function (func_x and func_y) are valid after running func_y.
But If I run func_x as I changed the name of the procedure in pack_a, func_x fails and invalidates func_x and func_y.
Why did in this last case both functions get invalid if func_y is using a different procedure which was not changed in pkg_a?

Thanks

Tom Kyte
December 26, 2002 - 5:46 pm UTC

because func_y in your session was made aware of the change indirectly by func_x I suppose. The server invalidated the package and everything you had dependent on it.

(these word problems -- very hard to follow, me head hurts now ;)



ORA-04061 error

A reader, June 25, 2003 - 5:09 pm UTC

I am running into this error as well. In my case I
changed just the implementation. I am not sure what
should be done to remove this error. I understand
why this error is but - to get back to a clean state
should i just log off from the application and log
back in - should i bounce the database? What is
typically done during developing a package (when it undergoes a lot of changes?)

Thank you - please keep up the great work!!

Tom Kyte
June 25, 2003 - 8:55 pm UTC

your implementation changed or maintained a state.

you rebuilt the implementation, state = "gone"

just reconnect or just resubmit the request.

Pauline, August 28, 2003 - 5:22 pm UTC

Tom,
When we compiled package body on production database at day time, we get errors of
ERROR 2003-08-21 16:35:17,081 - ConsignmentDAO.selectConsignment 1: consignmentID=159660087 lotID=0
java.sql.SQLException: ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "CORECODE.LOT_PKG" has been invalidated
ORA-04065: not executed, altered or dropped package body "CORECODE.LOT_PKG"
ORA-06508: PL/SQL: could not find program unit being called
ORA-06512: at "CORECODE.CONSIGNMENT_PKG", line 447
ORA-06512: at line 1


According to your comment, we changed the code people were running, they MUST get this
message and then they can "start over".

But in my impression, sometimes when we compile package on staging database, if user has
the long running transaction which executes the package, I could not compile that package
(getting time out while compiling the package) until user finished the transaction.

Since we won't be allow to reproduce this situation on production, I need your help to
explain the above errors occured on which situation

1. Users have the connections through web logic. The package code is 'cached'. We start to
compile package body. The users have not log out in their connection and then tried to
execute the package would get above errors.

2. The users were executing old version of package body. In the middle of process, we start
to compile package body. Then we receive the above errors.

we will appreciate your detail explanation.

Many thanks.

Tom Kyte
August 29, 2003 - 8:58 am UTC

#2 is the answer.


the user executed the package.... it has a state. the state was set. user stopped executing the package but the session remains, the state remains.


you came along and recompile the code.

bamm -- there goes that state.

user tries to execute the package -- but package reasonably says "hey, surprise surprise -- since the last time you saw me, I've totally changed and your prior state is *GONE*"


Your great answer let me know the mystery behind the seeing

A reader, September 04, 2003 - 10:19 am UTC

Tom,
Thanks very much for your detailed explanation. Now I know
what is the problem.

Pauline

A reader, December 15, 2003 - 11:09 am UTC


A reader, July 21, 2004 - 5:37 pm UTC

This is some sort of bug with Developer 2.1. There is a fix for it. Contact Oracle Support for a fix. Otherwise you will have to recompile all your forms that will be hectic.



I think this is relevant to this thread.

bhavani rao, December 21, 2004 - 12:31 pm UTC

I'm using
Oracle9i Enterprise Edition Release 9.2.0.5.0
Oracle® Developer Suite 10g (9.0.4)
and the in the database we have the parameter 'remote_dependencies_mode = signature'

Even then we are getting the ORA-04062 error when we connect thru the application server.
IS there any known bug in the above mentioned versions.
Thanks
Bhavani Rao


Tom Kyte
December 21, 2004 - 1:26 pm UTC

is there a chance that the signature did in fact *change*

YEs

bhavani rao, December 21, 2004 - 4:06 pm UTC

Yes , I have the parameter set and is running.

Thank you

A reader, December 21, 2004 - 5:03 pm UTC

It was because of the application server cache property.
The application was access the old FMX from the cache.
Thanks again
Bhavani Rao

Explanation of State.

Jack Custard, January 12, 2005 - 2:05 pm UTC

It was helpful to see the explanation of State as being to do with package variables - I couldn't understand why a recently compiled package body would not run.
It will run, EXCEPT when you have an still open session that has previously run the package. Hurrah. Thanks for quickly answering a subtle question.

Clarification concept - Invalid Packages

George J, January 28, 2005 - 4:43 am UTC


Sorry this is a bit of a long one....

I am currently arguing with a developer over an application's behaviour with regards handling of invalid packages.

Application X is making SQL calls and using package calls in-line to retrieve data, now while this is going on you can change the package being used, by reloading the complete package definition, this obviously causes the SQL to throw an ORA4061, state of packages had changed. This is in turn tells the app that something has gone wrong, however the app simply hands back only the data it has collected so far. I believe the app should say "oh well ORA SQL error, sorry no data. please try again later".

Now extracting the small section of SQL:

SELECT VIEW_001.COL1
FROM
VIEW_NUMBER_001
WHERE
( PACKAGE_001.FUNCTION_001(VIEW_001.COL1))

If this runs in a session, and in another session we reload the package, it cuts right into the SQL and stops it with the ORA-4061, "state of package has changed", as I would expect it to.

Now if I run this in one session, NOTE: wrapping a count function around the data column this time:

SELECT count(VIEW_001.COL1)
FROM
VIEW_NUMBER_001
WHERE
( PACKAGE_001.FUNCTION_001(VIEW_001.COL1))

The package reload in the other session waits until the SQL has finished, before it gets a crack the reload/rebuild.

My understanding, possibly flawed, is that the 2nd SQL, the count() is forcing the package to stay locked down until the result is completely collated, finally counted and returned, before allow the package to be manipulated.

The first SQL is constantly calling and releasing the package, so at some point Oracle is allowing the rebuild package to jump in, the split second it knows the package is no longer locked in use.

Is my thinking correct or have I missed something stupidly fundamental?

Thanks for you patience if you got this far!


Tom Kyte
January 28, 2005 - 7:38 am UTC

<quote>
I believe the app should say "oh well ORA SQL error,
sorry no data. please try again later".
</quote>

that is almost certainly true.


Locking of the code is just something totally transparent to you -- it totally depends on the plan the optimizer decided to use that morning -- index access, full scan, how many times it felt it needed to call it.


The larger problem here that you have is you are apparently dropping code into a running production system on a recurring basis. That -- that is a "no no"

Need help with invalid package state!!

Hanum, May 11, 2005 - 9:35 pm UTC

Tom, I have a problem with Package state in our intranet application. It's n-tier application with database/business layer / and application layer all in their own "tier"s. Now in our Java application we are having connection pooling for database (oracle 10g). When we do any changes to packages (or package body), and if i try to exec/call this package from java app, i'm getting "invalid package state" error 1st time. when we do it again (call it again), it runs fine. Since there is a connection pool, and we are not restarting our web server whenever database object changes, this error always comes and users are kind of frustated to try it again. So we thought of restarting webserver when ever we change any package, this way when we restart application , we will get fresh DB connections and we do not see this problem.

1) Will restarting the web server help solve this problem?
2) We do not actually want to do that, as whole idea of having n-tier app is to remove dependency (or so i was told),so any alternative to this?

Please advice,
Thanks

Tom Kyte
May 12, 2005 - 7:37 am UTC

what this message means is

a) your packages have global variables (a STATE)
b) your code in the middle tier must be dependent on this state
c) you instantiated this state, the code running in the database has set some values in the package
d) your code in the middle tier is COUNTING on this predicable state to be there
e) you come along in a PRODUCTION SYSTEM and wipe out this state, you in effect wipe out its memory.

Now what? the middle tier isn't aware that the code running in the database was erased, the state it has setup is gone.

We have to let the middle tier know.

How do you solve this?

a) schedule code upgrades in a production system during downtime.
b) bounce the middle tier when you wipe out the memory of the other tier (wipe out all memory)
c) don't KEEP a state in the database tier in the first place
d) have the middle tier catch this exception, decide if it is "OK" and retry the operation
e) call dbms_session.reset_package before putting a connection back into the pool (but beaware that has performance implications)

Invalid package state

Hanu, May 13, 2005 - 11:09 am UTC

Thanks Tom. I've removed global variables from package (and i'm guessing that'll remove State for this package) and tested a couple of times recompiling the package with users aleady logged in. This trick seems to be working as they have not seen that error message so far. Will follow up if i get problems again.

thanks for all your suggestions (valuable, ofcourse :-) )

Added Parameters in Stored procedure --throws 04062 in application

N.Venkatagiri, June 23, 2005 - 12:15 am UTC

Tom,

Developers added three parameters to an existing stored procedure
which has been called in two packages.
The package bodies are recompiled.(Specification of package
is not invalidated only body)

Now the form application is throwing 04062 error.


Please clarify, whether specification changes in procedure
requires forms recompiling.

(Database version :9.2.0.5 Forms : 6i)
Thanks


Tom Kyte
June 23, 2005 - 6:22 pm UTC

it should not, but I haven't touched forms in a decade, suggest either metalink or otn.oracle.com -> discussion forums for forms issues.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library