martes, 17 de diciembre de 2013

ORA-04068, ORA-04061, ORA-04065, ORA-06508 y ORA-06512

Probé este ejemplo en Oracle 11.2. Creé un paquete con una variable global, variable1, en la sesión roja abajo:
 
SQL> create or replace package package1
  2  is
  3  variable1 number := 1;
  4  procedure procedure1;
  5  end;
  6  /
 
Paquete creado.
 
SQL> create or replace package body package1
  2  is
  3  procedure procedure1
  4  is
  5  begin
  6  variable1 := variable1 + 1;
  7  dbms_output.put_line('Variable1 = '||variable1);
  8  end;
  9  end;
10  /
 
Cuerpo del paquete creado.
 
SQL>
 
Lo ejecuté en otra sesión azul, que se puede ver abajo. Oracle guardó el valor de la variable global entre cada ejecución:
 
SQL> set serveroutput on
SQL> exec package1.procedure1;
Variable1 = 2
 
Procedimiento PL/SQL terminado correctamente.
 
SQL> exec package1.procedure1;
Variable1 = 3
 
Procedimiento PL/SQL terminado correctamente.
 
SQL> exec package1.procedure1;
Variable1 = 4
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>
 
Regresé a la primera sesión, añadí otra variable global, variable2, y recompilé el paquete y su cuerpo:
 
SQL> create or replace package package1
  2  is
  3  variable1 number := 1;
  4  variable2 number;
  5  procedure procedure1;
  6  end;
  7  /
 
Paquete creado.
 
SQL> create or replace package body package1
  2  is
  3  procedure procedure1
  4  is
  5  begin
  6  variable1 := variable1 + 1;
  7  dbms_output.put_line('Variable1 = '||variable1);
  8  end;
  9  end;
10  /
 
Cuerpo del paquete creado.
 
SQL>
 
Luego , cuando volví a la segunda sesión y intenté a ejecutar el paquete, Oracle sabía que no podía creer el valor de la variable global porque una nueva variable global había sido añadida:
 
SQL> set serveroutput on
SQL> exec package1.procedure1;
BEGIN package1.procedure1; END;
 
*
ERROR en linea 1:
ORA-04068: se ha anulado el estado existente de los paquetes
ORA-04061: el estado existente de package "OPS$ORACLE.PACKAGE1" ha sido
invalidado
ORA-04065: package "OPS$ORACLE.PACKAGE1" no se ha ejecutado porque se ha
modificado o borrado
ORA-06508: PL/SQL: no se ha encontrado la unidad de programa llamada :
"OPS$ORACLE.PACKAGE1"
ORA-06512: en linea 1
 
SQL>
 
Entonces, cuando lo ejecuté por segunda vez, Oracle empezó a contar del principio otra vez:
 
SQL> set serveroutput on
SQL> exec package1.procedure1;
Variable1 = 2
 
Procedimiento PL/SQL terminado correctamente.
 
SQL> exec package1.procedure1;
Variable1 = 3
 
Procedimiento PL/SQL terminado correctamente.
 
SQL> exec package1.procedure1;
Variable1 = 4
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>
 
No es buena idea emplear variables globales si quieres evitar el error ORA-04068.