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 包开始/结束块之间的代码何时执行?的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL基础的执行部分

Oracle PL/SQL - 如果不满足条件,则退出开始结束块

SQLPLUS执行PL/SQL语句块

第三节PL/SQL编程

Oracle数据库之PL/SQL程序基础设计

ORA-29259 输入结束调用 utl_http.get_response PL/SQL