PL/SQL 包无效
我有一个使用包(PKG_MY_PACKAGE)的脚本。我将更改该包中查询中的一些字段,然后重新编译它(我不会更改或编译任何其他包)。我运行脚本并收到一个错误,看起来像是
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
我再次运行脚本(没有更改系统中的其他任何内容)并且脚本成功执行。
我认为在执行脚本之前进行编译时可以修复任何无效引用。这是 100% 可重现的,而且我使用这个脚本的次数越多,它就越烦人。什么可能导致这种情况,以及如何解决它?
(oracle 10g,使用 PL/SQL Developer 7)
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
背景
包的现有状态已被丢弃
意味着您的包(或主体)具有某种状态,但由于重新编译而丢失了。这是由存储在您的包中的全局变量引起的。
在 11.2.0.2 之前,常量确实也会导致此行为(请参阅 文档)。
由于该包已在您的会话中使用,Oracle 假定此状态与您相关。某些变量可能已更改,并且当您重新编译时,这些值将被重置。
抛出此异常,以便您的客户知道他们不能再依赖这些变量。
解决方案
解决方案(更改源)
DETERMINISTIC
函数替换全局变量(如 这个答案)PRAGMA SERIALLY_REUSABLE
导致 Oracle 在每次调用服务器时重新初始化全局变量。Background
existing state of packages has been discarded
means, 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)
DETERMINISTIC
functions (as suggested by this answer)PRAGMA SERIALLY_REUSABLE
causes Oracle to re-initialize the global variables with every call to the server.如果您正在脚本中运行内容,请在运行重新编译的代码之前尝试这些命令。
它们的作用正如其名称所暗示的那样。
If you're running stuff in a script try these commands in there prior to running the re-compiled code..
They do what the name might suggest.
您可能遇到的问题是:
检查此查询,在此all_objects视图中是否有您的包或包中使用的对象的条目
检查您的包是否具有全局变量?如果是,则检查这些变量是否未被任何其他会话更改,最好删除这些全局变量/使用函数
运行下面的脚本来编译架构中的所有对象
Possible issues you can have is:
check this query whether you have an entry of your package or objects used in your package in this all_objects view
Check your package is having global variables? if yes then check if those variable is not being changed by any other session preferable remove those global variables/use function
Run below script to compile all the objects in your schema
上述错误:ORA-06508: PL/SQL: 找不到被调用的程序单元。
当尝试调用无法找到的存储程序时导致。该程序可能已被删除或进行了不兼容的修改,或者编译时出现错误。
检查所有引用的程序(包括其包体)是否存在且兼容。
您可以运行此查询来查找无效对象,这可能会导致 ORA-06508 错误:
select
comp_id,
补偿名称,
版本,
地位,
命名空间,
图式
从
dba_注册表;
The above error : ORA-06508: PL/SQL: could not find program unit being called.
is caused when an attempt was made to call a stored program that could not be found. The program may have been dropped or incompatibly modified, or have compiled with errors.
Check that all referenced programs, including their package bodies, exist and are compatible.
You can run this query to find invalid objects, which may cause the ORA-06508 error:
select
comp_id,
comp_name,
version,
status,
namespace,
schema
from
dba_registry;