PL/SQL 包开始/结束块之间的代码何时执行?
Posted
技术标签:
【中文标题】PL/SQL 包开始/结束块之间的代码何时执行?【英文标题】:When is the code between a PL/SQL Package begin/end block executed? 【发布时间】:2009-11-24 20:20:58 【问题描述】:我有类似于下面sn-p的PL/SQL代码:
create or replace
package body MY_PACKAGE as
type array_type is table of char index by varchar2(1);
lookup_array array_type;
function DO_SOMETHING(input nvarchar2)
return varchar2 as
begin
-- Do something here with lookup_array
end DO_SOMETHING;
procedure init_array as
begin
lookup_array('A') := 'a';
lookup_array('B') := 'b';
-- etc
end init_array;
begin
init_array;
end MY_PACKAGE;
它使用静态查找数组来处理提供给 DO_SOMETHING 的数据。我的问题是,什么时候调用 init_array 并将 lookup_array 加载到内存中?什么时候编译包?第一次调用是什么时候?是否多次调用?有没有更好的方法来实现静态查找数组?
谢谢!
【问题讨论】:
这不会编译 - 你有包的主体,但没有 spc 是的,我知道;它也不会编译,因为 DO_SOMETHING 函数是空的。这只是一个 sn-p,让人们了解我正在尝试做什么。 一个有效的例子不会让人分心。 少一些对讨论没有贡献的cmets也不会分散注意力。 【参考方案1】:你可以参考这个链接: http://www.dba-oracle.com/plsql/t_plsql_lookup_tables.htm
“这意味着该过程在程序包初始化期间执行。因此,在会话的生命周期内,除非需要刷新缓存表,否则永远不会手动调用该过程。”
【讨论】:
优秀。正是我想要的。谢谢!【参考方案2】:第一季度。 “init_array
什么时候调用,lookup_array
什么时候加载到内存中?包编译的时候?第一次调用的时候?是不是多次调用?”
init_array 在调用包中的任何函数或过程时调用 - 即“及时”。每当包状态丢失时都会调用它(即每个会话可能会多次调用它)。
这对包状态丢失的情况有影响 - 例如当有人重新编译包时。在这种情况下,会发生以下顺序:
您的会话调用 do_something
- 首先调用 init_array
,然后执行 do_something
- 您的会话现在在其 PGA 中分配了一些内存来保存数组。
我的会话重新编译包。在这个阶段,为该包分配的会话内存被标记为“无效”。
您的会话调用do_something
- Oracle 检测到您的会话内存被标记为无效,并发出 ORA-04061“xxx 的现有状态已失效”。
如果您的会话再次调用do_something
,它会继续执行而不会出错 - 它首先调用init_array
,然后执行do_something
。
第二季度。 “有没有更好的方法来实现静态查找数组?”
只要您考虑到上述行为,我认为这种方法没有任何实际问题。
在某些情况下,我看到人们将 init 调用放在需要数组的每个函数/过程的开头 - 即,每当调用 do_something
时,它会检查是否需要初始化,如果需要,则调用init_array
。这种方法的优点是您可以自定义init_array
以仅初始化该功能/过程所需的位 - 如果init_array
做了很多工作,这可能是有利的 - 这可能有助于避免一次性启动每个会话的开销。
【讨论】:
以上是关于PL/SQL 包开始/结束块之间的代码何时执行?的主要内容,如果未能解决你的问题,请参考以下文章