出现这种情况的原因是因为,对于全局变量,每一个session会生成一个本地copy,如果程序重新编译的话,就会因程序里原变量找不到而丢弃该变量,继而导致这个错误。
也就是说在一个会话中调用程序包package时,会生成package中全局变量的副本,如果在另一个会话中对此package进行编译就会使前一个会话中的副本失效,故而产生错误。
要想避免这个错误,可以使程序捕获ORA-06508:的错误进行处理,也可以重新初始化会话
经检查,是由于OA接口中调用的PACKAGE的依赖包中定义了全局变量,若在package中定义了全局变量,该包被编译过但是应用没有重启或者没有刷新连接池,则会导致 "错误ORA-06508: PL/SQL: 无法找到正在调用 的程序单元"。
1.若PACKAGE中定义了全局变量或者全局常量,则此类包被称为有状态的包。
2.若有状态的包编译了,则上层应用连接池会认为该包无效了。
3.解决方式有两种
a.)简单粗暴的,直接重启上层应用。
b.)尽量不要在包中定义全局变量或者全局常量,若必须定义,则将全局变量或者全局常量定义到伴生包中。
“ORA-04068”错误是什么和它为什么发生,它会影响什么,以及建议的解决方法
下面我们将从定义“ORA-04068”错误开始。
注意: 在这篇文章的示例里使用的是Oracle 9.2.0.3,不过相同的概念在Oracle 10g 中应该也是适用的。
“ORA-04068”错误是什么和它为什么发生?
如果我们使用Oracle的oerr程序看看ORA-04068的定义,我们会得到下面的信息:
$oerr ora 04068
�
04068, 00000, "existing state of packages%s%s%s has been discarded"
�
// *Cause: One of errors 4060 - 4067 when attempt to execute a stored procedure.
�
// *Action: Try again after proper re-initialization of any
�
// application's state.
这个错误显示执行包的现有状态被另一个会话的一个动作无效化了。这个“状态”涉及包在规范或体中定义的任何全局变量(包括常量)。引起这个错误的动作一般是(但不局限于此)在得到了发生错误的会话所使用的连接之后包的重新编译。Oracle 建议的动作是重新初始化应用程序状态以调整包的新状态后重新尝试.
最简单的解决方法是使用无状态的包(我们的解决方法1),如果可以这样,那么这就是我所推荐的。你应该努力使你的包无状态化。
注意在包规范或包体中没有全局变量或常量。换句话说,这个包是“无状态的”。如:
有个叫做pkg 的包具有一个叫做p的存储过程,如下所示
有个叫做pkg 的包具有一个叫做p的存储过程,如下所示:
create or replace package pkg as
procedure p;
end pkg;
/
下面所显示的包pkg的包体定义了存储过程p只是插入一个常量1到我们先前定义的表t中
create or replace package body pkg as
procedure p
is
begin
insert into t(x) values (1);
end p;
end pkg;
/
------------------
注意在包规范或包体中没有全局变量或常量。换句话说,这个包是“无状态的”。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。