我的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加载到内存中?什么时候编译包?什么时候第一次打电话?是不是一次被召唤?有没有更好的方法来实现静态查找数组?
谢谢!
答案 0 :(得分:5)
您可以参考此链接: http://www.dba-oracle.com/plsql/t_plsql_lookup_tables.htm
“这意味着在程序包初始化期间执行该过程。因此,在会话的生命周期中,除非需要刷新缓存的表,否则永远不会手动调用该过程。”
答案 1 :(得分:4)
<强> Q1。 “何时调用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
。
<强> Q2。 “有没有更好的方法来实现静态查找数组?”
我认为这种方法没有任何实际问题,只要你考虑上述行为。
在某些情况下,我看到人们在需要数组的每个函数/过程的开头放置init调用 - 即每当调用do_something
时,它会检查是否需要初始化,以及是否需要初始化所以请致电init_array
。这种方法的优点是您可以自定义init_array
以仅初始化该函数/过程所需的位 - 如果init_array
做了大量工作,这可能是有利的 - 这可能有助于避免大的每次会话的一次性启动开销。