Почему я получаю 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.