web-dev-qa-db-fra.com

Pourquoi est-ce que j'obtiens PLS-00302: le composant doit être déclaré quand il existe?

J'utilise Oracle 10.2.

Je travaille dans certains scripts pour déplacer certains objets Oracle d'un SCHEMA (S1) à un autre (S2). Je crée les fonctions avec le rôle DBA. Lorsqu'elle est déplacée, une de mes fonctions devient invalide, mais je ne comprends pas pourquoi. Son code va dans ce sens:

MY_FUNC

CREATE OR REPLACE FUNCTION S2."MY_FUNC" RETURN VARCHAR2 IS
   something VARCHAR2;
   othervar VARCHAR2 (50):= 'TEST';   
BEGIN
   something := S2.MY_FUNC2();
    /*some code*/
    return othervar;
END;
/

Si j'utilise MY_FUNC2 Sans le schéma, cela fonctionne:
something := MY_FUNC2(); au lieu de something := S2.MY_FUNC2();

My_FUNC2

CREATE OR REPLACE FUNCTION S2."MY_FUNC2" RETURN VARCHAR2 IS
       something BOOLEAN;
       othervar VARCHAR2 (50) := 'TEST2';           
    BEGIN
       /*some code*/
        return othervar;
    END;
    /

MY_FUNC2 a un synonyme comme celui-ci:

 CREATE OR REPLACE PUBLIC SYNONYM "MY_FUNC2" FOR "S2"."MY_FUNC2"

MY_FUNC Compile avec des erreurs:

PLS-00302: le composant 'MY_FUNC2' doit être déclaré

Je ne comprends pas pourquoi j'obtiens cette erreur, lorsque mes fonctions étaient dans l'autre schéma (S1), elles avaient exactement la même structure et le synonyme a été créé exactement de la même manière (mais pointant vers S1) et MY_FUNC bien compilé.

Je n'ai pas créé ces fonctions et synonyme à l'origine. Est-il possible que certains privilèges me manquent dans S2, afin que MY_FUNC Puisse fonctionner correctement?

10
Dzyann

Vous pouvez obtenir cette erreur si vous avez un objet du même nom que le schéma. Par exemple:

create sequence s2;

begin
  s2.a;
end;
/

ORA-06550: line 2, column 6:
PLS-00302: component 'A' must be declared
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored

Lorsque vous faites référence à S2.MY_FUNC2 le nom de l'objet est en cours de résolution, il n'essaie donc pas d'évaluer S2 comme nom de schéma. Lorsque vous l'appelez simplement comme MY_FUNC2 il n'y a pas de confusion, donc ça marche.

La documentation explique la résolution de nom . La première partie du nom d'objet qualifié - S2 ici - est évaluée en tant qu'objet sur le schéma actuel avant d'être évaluée en tant que schéma différent.

Ce n'est peut-être pas une séquence; d'autres objets peuvent provoquer la même erreur. Vous pouvez vérifier l'existence d'objets du même nom en interrogeant le dictionnaire de données.

select owner, object_type, object_name
from all_objects
where object_name = 'S2';
16
Alex Poole

Je suis venu ici parce que j'avais le même problème.
Le problème pour moi était que la procédure était définie dans le corps du package, mais pas dans l'en-tête du package.
J'exécutais ma fonction avec une instruction BEGIN END perdue.

7
Tenzin