4. Dezember 2008

PL/SQL Packages intialisieren

English title: PL/SQL initializing code ...

Wusstet Ihr, dass man in einem PL/SQL-Package auch Initialisierungscode hinterlegen kann; man braucht also nicht unbedingt eine Prozedur oder Funktion "init" - dazu gibt es im Package Body ein vorgesehenes Konstrukt:
Did you know that you can add initializing code to your PL/SQL packages? You don't need a special "init" procedure or function - there is a special language feature in the package body:
create or replace package test_init is
  g_max_salary number;
  function return_global_var return number;
end test_init;
/

create or replace package body test_init is
  function return_global_var return number is
  begin
    return g_max_salary;
  end return_global_var;

  begin
    select max(sal) into g_max_salary from emp;
end test_init;
/
Der rote Code ist der Initialisierungscode; er wird bei der ersten Nutzung des PL/SQL-Paketes aufgerufen. Als Beispiel rufe ich einfach nur die globale Variable ab:
The code is the initialization code; it is being executed on the first usage of the package. The following example just gets the global package variable:
SQL> var v_sal number
SQL> exec :V_SAL := test_init.g_max_salary

PL/SQL-Prozedur erfolgreich abgeschlossen.

SQL> print

     V_SAL
----------
      5000

Man sieht es recht selten, deshalb war mir gar nicht bewußt, dass das geht ... Man lernt halt nie aus ...
Until I've heard about this a few weeks ago I did not realize that this is possible ... Live and learn ...

Kommentare:

Anonym hat gesagt…

Ich nutze das gelegentlich. Vorsicht ist jedoch geboten, da die Inititialisierung tatsächlich bei jedem Laden des Packages, also ggf. mehrmals in einer Session ausgeführt wird.

Carsten Czarski hat gesagt…

Hallo,

Richtig; bei jedem *Laden* des Packages. Solange ein Package nicht explizit invalidiert wird (DBMS_SESSION) wird es damit einmal pro Session ausgeführt, und zwar dann, wenn das Package zum ersten Mal angesprochen wird. Das lässt sich auch leicht nachvollziehen:

create or replace package test_init is
g_var number := 0;
function return_global_var return number;
end test_init;
/

create or replace package body test_init is
function return_global_var return number is
begin
return g_var;
end return_global_var;

begin
g_var := g_var + 1;
end test_init;
/

Wie man sieht, wird die Variable g_var hochgezählt - Nun test man das ...

SQL> select test_init.return_global_var from dual;

RETURN_GLOBAL_VAR
-----------------
1

1 Zeile wurde ausgewählt.

SQL> select test_init.return_global_var from dual;

RETURN_GLOBAL_VAR
-----------------
1

1 Zeile wurde ausgewählt.

SQL> select test_init.return_global_var from dual;

RETURN_GLOBAL_VAR
-----------------
1

1 Zeile wurde ausgewählt.

Die Init-Abschnitte sind vor allem zum Aufsetzen des Package-State gedacht; man sollte generell vorsichtig sein, hier gar DML zu verwenden ...

Beliebte Postings