丢弃现有的包状态 - Oracle

时间:2011-06-23 13:04:46

标签: oracle

我使用的是Oracle,我在一些触发器和包上修改了代码。 当我运行修改代码并尝试对表执行更新的脚本文件(触发触发器)时,我将丢弃现有的包状态

我收到了一堆错误

ORA-04068:
ORA-04061:
ORA-04065:
ORA-06512:--Trigger error -- line 50
ORA-04088:

此错误仅在第一次发生。任何避免这种情况的输入都将非常感激。谢谢!

3 个答案:

答案 0 :(得分:4)

serially_reusable仅对常量包变量有意义。

只有一种方法可以避免此错误并保持性能(reset_package确实不是一个好选择)。避免PL / SQL包中的任何包级变量。您的Oracle服务器内存不是存储状态的正确位置。

如果某些内容确实没有改变,计算起来很昂贵,并且函数的返回值可以反复重复使用而无需重新计算,那么DETERMINISTIC在这方面有帮助

示例:请勿这样做: varchar2(100)cached_result;

function foo return varchar2 is
begin
  if cached_result is null then
     cached_result:= ... --expensive calc here
  end if; 
 return cached_result;
end foo;

做这个INSTEAD

function foo return varchar2 DETERMINISTIC is
begin
  result:=... --expensive calc here
  return result;
end foo;

确定性告诉Oracle,对于给定的输入,结果不会改变,因此它可以缓存结果并避免调用函数。

如果这不是您的用例,并且您需要跨会话共享变量,请使用表格并进行查询。如果它以任何频率使用,你的表将最终进入缓冲区高速缓冲存储器,这样你就可以获得所需的内存存储而不会出现会话变量的问题

答案 1 :(得分:3)

您的脚本很可能会缓存过时的代码。所以,从Michael Pakhanstovs链接中你可以运行

DBMS_SESSION.RESET_PACKAGE 

在脚本的开头或使用

PRAGMA SERIALLY_REUSABLE; 

在你的剧本中。

但请注意两者的含义:

http://download.oracle.com/docs/cd/B13789_01/appdev.101/b10807/13_elems046.htm

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sessio.htm#i1010767

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2298325131459

在DBMS_SESSION.RESET_PACKAGE上的AskTom:

  

dbms_session.reset_package,而且很多   更快,然后登录和退出,有   一些性能影响(不是   很快就明白了!)。   那,它将彻底摧毁整个   会话状态,例如:任何打开的游标   你有(准备好的陈述)   好。

AskTom on PRAGMA SERIALLY_REUSABLE:

  

它基本上是在说'如果你使用的话   包,你不保存状态   包裹,并希望避免   具有包装的持久性   在你的会话中 - 减少内存 - 使用   这种

答案 2 :(得分:0)

我有同样的问题。

我的情况是我为一个程序包编写了一个动态创建脚本,然后在下一个脚本行中调用该程序包中的过程。我认为您的处境也一样。

我检测到的问题是软件包生成的时间戳与过程调用的时间戳相同。如今,随着服务器越来越快,它发生了。

因此,在生成脚本中,我在包创建行之后介绍了<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="newText"></div>

解决了这个问题!