Paquet PL/SQL invalidé
j'ai un script qui utilise un paquet (PKG_MY_PACKAGE). Je vais modifier certains champs d'une requête dans ce paquet et le recompiler (Je ne change ni ne compile aucun autre paquet). J'exécute le script et j'obtiens une erreur qui ressemble à
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
j'exécute le script à nouveau (sans changer quoi que ce soit d'autre dans le système) et le script s'exécute avec succès.
j'ai pensé que lorsque j'ai compilé avant d'exécuter le script qui corrigerait n'importe quel invalide référence. C'est 100% reproductible, et de plus j'utilise ce script le plus ennuyeux c'est. Qu'est-ce qui pourrait causer ça, et qu'est-ce qui pourrait arranger ça?
(oracle 10g, using PL / SQL Developer 7)
4 réponses
Background
existing state of packages has been discarded
signifie que votre Colis avait une sorte d'état.
ceci est causé par une variable globale stockée dans votre paquet.
Jusqu'à 11.2.0.2, les constantes ont aussi causé ce comportement (voir documentation).
puisque le paquet a déjà été utilisé dans votre session, Oracle suppose que cet état est pertinent pour vous. Certaines de ces variables peuvent avoir des valeurs différentes maintenant, et quand vous recompilez le Corps, les valeurs sont réinitialisées.
cette exception est jetée, pour que vos clients sachent qu'ils ne peuvent plus compter sur ces variables.
Solutions
- supprimer toutes les variables et constantes globales (avant 11gR2) à partir du corps du paquet si possible
- Remplacer les variables globales par
DETERMINISTIC
fonctions (suggérées par cette réponse) - définition des paquets avec
PRAGMA SERIALLY_REUSABLE
fait qu'Oracle réinitialise les variables globales à chaque appel au serveur. - fermez votre session et reconnectez-vous avant d'appeler à nouveau le paquet.
- Réinitialiser l'état manuellement (voir réponse de Paul James)
si vous exécutez des choses dans un script, essayez ces commandes avant d'exécuter le code recompilé..
exec DBMS_SESSION.RESET_PACKAGE
exec DBMS_SESSION.MODIFY_PACKAGE_STATE( DBMS_SESSION.REINITIALIZE )
Ils font ce que le nom pourrait suggérer.
questions possibles que vous pouvez avoir est:
le paquet / procédure que vous appelez est invalide (bien qu'il puisse fonctionner s'il est appelé indépendamment)) cochez cette requête si vous avez une entrée de votre colis ou objets utilisés dans votre colis dans ce all_objects view
select * from all_objects where status = 'INVALID' and owner = 'SCHEMA_NAME';
vérifiez que votre paquet a des variables globales? si oui, alors vérifier si ces variables ne sont pas modifiées par une autre session. il est préférable de supprimer ces variables globales/utiliser la fonction
exécuter en dessous de script pour compiler tous les objets dans votre schéma
commencer dbms_utility.compile_schema ('SCHEMA_NAME', false); fin;
- dernière option si aucune des options ci-dessus ne fonctionne, supprimez toutes les procédures/fonctions de votre paquet, ajoutez une nouvelle fonction et essayez d'exécuter votre fonction à partir du déclencheur. vérifiez si cela fonctionne alors votre paquet est dans une serrure spéciale. Après avoir ajouté une nouvelle fonction/proc, son état sera à nouveau valide et vous pourrez alors ajouter toutes vos fonctions/procs actuelles et supprimer la nouvelle fonction/proc ajoutée.
L'erreur ci-dessus : ORA-06508: PL/SQL: impossible de trouver le programme de l'unité d'être appelé.
est causée lors d'une tentative a été faite pour appeler un programme qui n'a pas pu être trouvé. Le programme peut avoir été abandonné ou modifié de façon incompatible, ou avoir été compilé avec des erreurs.
vérifiez que tous les programmes référencés, y compris leurs corps de paquets, existent et sont compatibles.
vous pouvez exécuter cette requête pour trouver des objets invalides, ce qui peut causer L'ORA-06508 erreur:
sélectionner comp_id, comp_name, version, statut, espace de noms, schéma de db_registry;