为什么我会得到PLS-00302:组件必须在它存在时声明?

Dzy*_*ann 10 oracle plsql oracle10g

我正在使用Oracle 10.2.

我正在使用一些脚本将一些ORACLE对象从一个SCHEMA(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;
/
Run Code Online (Sandbox Code Playgroud)

如果我使用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;
    /
Run Code Online (Sandbox Code Playgroud)

MY_FUNC2有一个这样的同义词:

 CREATE OR REPLACE PUBLIC SYNONYM "MY_FUNC2" FOR "S2"."MY_FUNC2"
Run Code Online (Sandbox Code Playgroud)

MY_FUNC 编译错误:

PLS-00302:必须声明组件'MY_FUNC2'

我不明白为什么我得到这个错误,当我的函数在其他模式(S1)中时,它们具有完全相同的结构并且同义词创建完全相同(但指向S1)并且MY_FUNC编译良好.

我最初没有创建这个函数和同义词.是否有可能我在S2中缺少某些特权,所以MY_FUNC可以正常工作吗?

Ale*_*ole 16

如果您有一个与架构同名的对象,则可能会收到该错误.例如:

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
Run Code Online (Sandbox Code Playgroud)

当您引用S2.MY_FUNC2正在解析的对象名称时,它不会尝试将S2评估为模式名称.当你只是打电话给它,因为MY_FUNC2没有混乱,所以它的工作原理.

该文档解释了名称解析.第一部分限定对象名称 - 此处为S2 - 在被评估为不同模式之前,将被评估为当前模式上的对象.

它可能不是一个序列; 其他对象可能会导致相同的错误.您可以通过查询数据字典来检查是否存在具有相同名称的对象.

select owner, object_type, object_name
from all_objects
where object_name = 'S2';
Run Code Online (Sandbox Code Playgroud)


Ten*_*zin 7

我来这里是因为我有同样的问题。
对我来说,问题在于该过程是在程序包主体中定义的,而不是在程序包头中定义的。
我正在使用Lost BEGIN END语句执行函数。