Почему я получаю PLS-00302: компонент должен быть объявлен, когда он существует?

Я использую Oracle 10.2.

Я работаю в некоторых сценариях, чтобы переместить некоторые объекты ORACLE из одной схемы (S1) в другую (S2). Я создаю функции с ролью DBA. При перемещении одна из моих функций становится недействительной, но я не понимаю, почему. Его код идет по следующим строкам:

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;
/

если я использую MY_FUNC2 без схемы, работает:
something := MY_FUNC2(); вместо 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 имеет такой синоним:

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

MY_FUNC компилируется с ошибками:

PLS-00302: компонент "MY_FUNC2" должен быть объявлен

Я не понимаю, почему я получаю эту ошибку, когда мои функции были в другой схеме (S1), они имели точно такую же структуру, и синоним был создан точно так же (но указывая на S1) и MY_FUNC составлен штраф.

Я не создавал эти функции и синоним первоначально. Возможно ли, что мне не хватает некоторых привилегий в S2, поэтому MY_FUNC может работать правильно?

2 ответов


вы можете получить эту ошибку, если у вас есть объект с таким же именем, как у схемы. Например:

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

когда вы смотрите S2.MY_FUNC2 имя объекта решается, поэтому он не пытается оценить S2 как имя схемы. Когда вы просто называете это как MY_FUNC2 нет никакой путаницы, поэтому он работает.

документация объясняет разрешение имен. Первая часть имени квалифицированного объекта-S2 здесь-оценивается как объект в текущей схеме прежде чем он будет оценен как другая схема.

это может быть не последовательность; другие объекты могут вызвать ту же ошибку. Вы можете проверить наличие объектов с тем же именем, запросив словарь данных.

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

Я пришел сюда, потому что у меня была такая же проблема.
Проблема заключалась в том, что процедура была определена в теле пакета, но не в заголовке пакета.
Я выполнял свою функцию с помощью оператора lose BEGIN END.