Q1. "When is init_array
called and lookup_array
loaded into memory? When the package is compiled? When it is called for the first time? Is it called more than once?"
init_array is called when any function or procedure in the package is called - i.e. "just in time". It will be called whenever the package state is lost (i.e. it may be called more than once per session).
This has implications for the scenario where package state is lost - e.g. when someone recompiles the package. In this scenario, the following sequence occurs:
Your session calls do_something
- init_array
is called first, then do_something
executes - your session now has some memory allocated in its PGA to hold the array.
My session recompiles the package. At this stage, your session's memory that is allocated for that package is marked "invalid".
Your session calls do_something
- Oracle detects that your session's memory is marked invalid, and issues ORA-04061 "existing state of xxx has been invalidated".
If your session calls do_something
again, it proceeds without error - it first calls init_array
and then executes do_something
.
Q2. "Is there a better way to implement a static lookup array?"
I don't see any real problems with this approach, so long as you take into account the behaviour described above.
In some cases I've seen people put the init call at the start of each function/procedure that needs the array - i.e. whenever do_something
is called, it checks to see if it needs to initialise, and if so calls init_array
. The advantage of this approach is that you can customise init_array
to only initialise the bits that that function/procedure needs - which might be advantageous if init_array
does a lot of work - which might help to avoid a big one-time startup overhead for each session.