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)

24
demandé sur Peter Lang 2010-03-23 21:48:10

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)
19
répondu Peter Lang 2017-05-23 11:46:21

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.

21
répondu Paul James 2010-03-24 08:53:56

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.
0
répondu Ankur Bhutani 2016-12-23 13:24:30

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;

0
répondu Paul 2017-06-09 03:57:51