oracle PL/SQL包无效

jhiyze9q  于 2023-05-16  发布在  Oracle
关注(0)|答案(4)|浏览(282)

我有一个使用包(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 10 g,使用PL/SQL Developer 7)

piah890a

piah890a1#

背景

existing state of packages has been discarded意味着你的包(或主体)有某种状态,但在重新编译时丢失了。
这是由存储在您的Package中的全局变量引起的。
在www.example.com之前11.2.0.2,常量也会导致这种行为(请参阅文档)。
由于包已在会话中使用,Oracle假定此状态与您相关。某些变量可能已更改,重新编译时,这些值将重置。
这个异常被抛出,这样你的客户端就知道他们不能再依赖这些变量了。

解决方案

  • 再次调用,意识到状态已重置
  • 关闭会话并重新连接,然后再调用包。
  • 手动重置状态(参见Paul James' answer
    解决方案(更改源)
  • 如果可能,删除所有全局变量(和11gR2之前的常量
  • 将它们移到包头,这样至少可以重新编译Body
  • DETERMINISTIC函数替换全局变量(如this answer所建议)
  • 使用PRAGMA SERIALLY_REUSABLE定义包会导致Oracle在每次调用服务器时重新初始化全局变量。
mgdq6dx1

mgdq6dx12#

如果你正在运行脚本中的东西,在运行重新编译的代码之前,尝试这些命令。

exec DBMS_SESSION.RESET_PACKAGE
exec DBMS_SESSION.MODIFY_PACKAGE_STATE( DBMS_SESSION.REINITIALIZE )

他们做的是名字所暗示的。

ldxq2e6h

ldxq2e6h3#

您可能遇到的问题包括:

  • 您正在调用的包/过程无效(尽管如果单独调用它可以工作),请检查此查询是否在此all_objects视图中有包或包中使用的对象的条目
select * from all_objects where status = 'INVALID' and owner = 'SCHEMA_NAME';
  • 检查你的包是否有全局变量?如果是,则检查这些变量是否未被任何其它会话改变,优选地移除这些全局变量/使用函数
  • 运行下面的脚本以编译架构中的所有对象
begin
   dbms_utility.compile_schema('SCHEMA_NAME', false); 
end;
  • 最后一个选项,如果以上都不起作用,则从包中删除所有过程/函数,添加新函数并尝试从触发器运行函数。检查如果这工作,那么你的包是在特殊锁.添加新的函数/proc后,它的状态将再次有效,然后您可以添加所有实际的函数/proc并删除新添加的函数/proc。
vof42yt1

vof42yt14#

上述错误:ORA-06508:PL/SQL:找不到正在调用的程序单元。
当试图调用找不到的存储程序时,会导致。该程序可能已被删除或被不兼容地修改,或者编译时出错。
检查所有引用的程序,包括它们的包体,是否存在并且兼容。
您可以运行此查询来查找无效对象,这可能会导致ORA-06508错误:
从dba_registry中选择comp_id、comp_name、version、status、namespace、schema;

相关问题