本文主要是介绍ORA-04068: existing state of packages has been discarded,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一.版本信息
操作系统版本:
AIX 6100
数据库版本:
11.2.0.3(psu5)
二.错误描述
#因为该错误有很多可能的原因,所以此处描述场景的时候需要详细点
该错误是我在解决oracle "Doc ID 1413756.1"所描述错误时触发的。(具体可以见我的前面的博客)
1. 按照"Doc ID 1413756.1"提供的临时解决方案,我分别执行了如下命令
-- Login as sys user.
SQL> sqlplus / as sysdba
-- From the sqlplus execute the following:
-- Drop the DBSNMP user by executing catnsnmp.sql script.
SQL> @$ORACLE_HOME/rdbms/admin/catnsnmp.sql
-- Create the DBSNMP user by executing catsnmp.sql
SQL> @$ORACLE_HOME/rdbms/admin/catsnmp.sql
#删除时报了某角色不存在,重建时报了一些object已存。没有大的问题。
2. 为了确保没有问题我再次重复了上面删除和重建DBSNMP用户的命令(在同一个会话中)
#删除用户时,跟首次执行一致,但是在重建用户时我看到了如下报错:
Package body created.
Package body created.
declare
*
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package "DBSNMP.BSLN" has been invalidated
ORA-04065: not executed, altered or dropped package "DBSNMP.BSLN"
ORA-06508: PL/SQL: could not find program unit being called: "DBSNMP.BSLN"
ORA-06512: at line 18
PL/SQL procedure successfully completed.
#从报错中其实我们已经可以看出一些端倪出来,报错说package的state(申明)已经无效,然后导致了后面的错误
三. 错误原因及解决方案
查找我们的老帮手MOS发现了"Doc ID 1161225.1"这篇NOTE可以解释我遇到的问题,我贴出了其中一部分:
When a package is compiled, altered or an object on which the package depends is altered, all copies of that package in the shared pool are flagged as invalid.
The next invocation of the package from another database session ( even if it is the same username) sees that this flag is set and goes to get a new copy. <span style="color:#ff0000;">If the package has package state, i.e. it has one or more package variables that would normally persist across calls to the package within the same session, then ORA-4068 error is raised to indicate to the caller that that package state (i.e the current values of those package variables) has been lost</span>. When the ORA-4068 is raised, ORACLE will throw away all existing instantiations of the package. When the package (more properly, the subprogram referring to the package) is re-executed, ORACLE will re-instantiate the package automatically (If possible), which will typically succeed, and re-execution of the subprogram will succeed.
The mechanism is not sensitive enough to check whether the calling session actually referred to any of the package variables so you always get the error in these situations if the package you are calling has package variables defined. <span style="color:#ff0000;">This is quite common therefore if your program calls a system level package (typically beginning DBMS_ or UTL_) that has been recompiled, as the majority of them have at least one package variable defined.</span>
#大概就是说一个程序包被编译或者alert或者包所依赖的对象被alert,那么shared pool(注意此处是shared pool )中该包的copies都会标记为失效状态。
其他的会话再次调用该报的时候发现失效标记后,会去获取新的copy。
如果这个包有申明的话,比如这个包申明了变量,那么我们在同一个会话中再次调用这个变动过的包,就会报ORA-4068这个错误,向调用者表明该包的申明已经失效。(这就是我第二次执行重建DBSNMP用户报错的原因)。
#这个报错我们可以看错是一个警告,我们无需处理,再次调用就没有问题了。
四. 相关知识
#上面我们只列出了我工作中碰到的情况,还有一些其他情况会触发该报错
"Doc ID 106206.1"中列出了一些常见的场景,我们也可以在MOS中直接搜该报错查看符合自己问题的note
这篇关于ORA-04068: existing state of packages has been discarded的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!