oracle - loop - ora-04061
Paquete PL/SQL invalidado (4)
El error anterior: ORA-06508: PL / SQL: no se pudo encontrar la unidad de programa que se está llamando.
se produce cuando se intenta llamar a un programa almacenado que no se pudo encontrar. Es posible que el programa se haya caído o modificado de forma incompatible, o se haya compilado con errores.
Compruebe que todos los programas a los que se hace referencia, incluidos sus cuerpos de paquetes, existen y son compatibles.
Puede ejecutar esta consulta para encontrar objetos no válidos, lo que puede causar el error ORA-06508:
seleccione comp_id, comp_name, versión, estado, espacio de nombres, esquema de dba_registry;
Tengo un script que hace uso de un paquete (PKG_MY_PACKAGE). Cambiaré algunos de los campos de una consulta en ese paquete y luego los compilaré (no cambio ni compilo ningún otro paquete). Ejecuto el script y me sale un error que parece
ORA-04068: existing state of packages has been discarded ORA-04061: existing state of package body "USER3.PKG_MY_PACKAGE" has been invalidated ORA-04065: not executed, altered or dropped package body "USER3.PKG_MY_PACKAGE" ORA-06508: PL/SQL: could not find program unit being called: "USER3.PKG_MY_PACKAGE" ORA-06512: at line 34
Vuelvo a ejecutar el script (sin cambiar nada más en el sistema) y el script se ejecuta correctamente.
Pensé que cuando compilaba, antes de ejecutar el script, se corregirían las referencias no válidas. Esto es 100% reproducible, y cuanto más uso este script, más molesto se vuelve. ¿Qué podría causar esto, y qué lo arreglaría?
(Oracle 10g, usando PL / SQL Developer 7)
Posibles problemas que puede tener es:
El paquete / procedimiento al que llama no es válido (aunque puede funcionar si se llama de forma independiente) compruebe esta consulta si tiene una entrada de su paquete u objetos utilizados en su paquete en esta vista de todos los objetos
seleccione * de all_objects donde status = ''INVALID'' y owner = ''SCHEMA_NAME'';
Compruebe que su paquete tiene variables globales? Si es así, compruebe si esa variable no está siendo modificada por ninguna otra sesión. Preferiblemente, elimine esas variables globales / función de uso.
Ejecutar debajo del script para compilar todos los objetos en su esquema
comience dbms_utility.compile_schema (''SCHEMA_NAME'', falso); fin;
- Última opción si ninguno de los anteriores funciona, luego elimine todos los procedimientos / funciones de su paquete, agregue una nueva función e intente ejecutar su función desde el activador. Compruebe si esto funciona, entonces su paquete está en bloqueo especial. Después de agregar una nueva función / proc, su estado volverá a ser válido y luego podrá agregar todas sus funciones / procs reales y eliminar la función / proc recién agregada.
Si está ejecutando cosas en una secuencia de comandos, pruebe estos comandos antes de ejecutar el código compilado nuevamente.
exec DBMS_SESSION.RESET_PACKAGE
exec DBMS_SESSION.MODIFY_PACKAGE_STATE( DBMS_SESSION.REINITIALIZE )
Hacen lo que el nombre podría sugerir.
Fondo
existing state of packages has been discarded
significa que su Paquete tenía algún tipo de estado.
Esto se debe a una variable global almacenada en el cuerpo de su paquete.
Hasta el 11.2.0.2, las constantes también causaron este comportamiento (ver documentation ).
Dado que el paquete ya se ha utilizado en su sesión, Oracle asume que este estado es relevante para usted. Algunas de estas variables pueden tener diferentes valores ahora, y cuando recompila el Cuerpo, los valores se restablecen.
Se lanza esta excepción para que sus clientes sepan que ya no pueden confiar en esas variables.
Soluciones
- Eliminar todas las variables y constantes globales (antes de 11gR2) del cuerpo del paquete si es posible
- Reemplace las variables globales por funciones
DETERMINISTIC
(como lo sugiere esta respuesta ) - La definición de paquetes con
PRAGMA SERIALLY_REUSABLE
hace que Oracle reinicialice las variables globales con cada llamada al servidor. - Cierre su sesión y vuelva a conectarse antes de volver a llamar al paquete.
- Restablecer el estado manualmente (ver la respuesta de Paul James )