Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 为什么我得到PLS-00302:组件存在时必须声明?_Oracle_Plsql_Oracle10g - Fatal编程技术网

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

Oracle 为什么我得到PLS-00302:组件存在时必须声明?,oracle,plsql,oracle10g,Oracle,Plsql,Oracle10g,我正在使用Oracle 10.2 我正在使用一些脚本将一些ORACLE对象从一个模式(S1)移动到另一个模式(S2)。 我正在使用DBA角色创建函数。 移动时,我的一个函数无效,但我不明白为什么。 其代码大致如下: 我的功能 CREATE OR REPLACE FUNCTION S2."MY_FUNC" RETURN VARCHAR2 IS something VARCHAR2; othervar VARCHAR2 (50):= 'TEST'; BEGIN somethi

我正在使用Oracle 10.2

我正在使用一些脚本将一些ORACLE对象从一个模式(S1)移动到另一个模式(S2)。 我正在使用DBA角色创建函数。 移动时,我的一个函数无效,但我不明白为什么。 其代码大致如下:

我的功能

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
,它会起作用:
某物:=MY_FUNC2()而不是
某物:=S2.MY_FUNC2()

我的功能2

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
可以正常工作?

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

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语句执行我的函数

您是从s1还是s2调用函数?如果从s1调用,则需要在s2上授予grant execute权限。我的函数2到s1。据我所知,这与调用无关,它甚至不编译。所以我只是想确定一下,因为你的问题并不清楚。您是作为sys还是s2登录的?您首先创建了MY_FUNC2,然后创建了public同义词,然后创建了MY_FUNC?如果您是具有create public同义词权限的SYS或S2,并且按照此顺序进行编译,则没有理由不编译(除了my_func具有varchar2声明;没有精确性)@Aramillo所有内容都在S2中,并且我使用DBA角色登录。Alex在下面描述了这个问题。另一个解决方案:谢谢Alex!这似乎是有道理的,它们有一个与模式同名的视图。有没有办法让Oracle将S2解释为一个模式而不是视图?@Dzyann-不符合这些搜索规则。为什么你有资格在所有虽然;如果你指的是同一个模式中的某个东西,那么在所有东西前面加上模式名并没有什么真正的好处?好吧,一开始我只是不明白为什么这在一个模式中有效而在另一个模式中无效。同样在理解了这个问题之后,我意识到其他模式也会发生这种情况。从S1调用MY_FUNC2失败,因为Oracle首先找到S2视图的同义词,而不是S2模式。基本上,因为我不能强迫oracle将S2解释为模式,所以我认为应该改变S2视图的名称及其公共同义词;有冲突的标识符充其量只会引起混乱。有些人喜欢使用匈牙利符号或变体,这可能会避免这种事情,但另一些人鄙视它,标识符长度的限制可能会让它变得尴尬。(S2对于视图名称或架构名称来说似乎不是很有描述性,但并不总是在我们的控制之下……)再次感谢,您提供了很多帮助。S2不是真名,我只是用它来简化我的帖子,真名其实很好,我正试图想出一个很好的简短的替代方案。祝福你:)我也遇到了同样的问题,忘记了包SPECi遇到了同样的情况,但在遗留代码中。这个程序本来是本地的,外界看不见。解决方案是寻找一些可以调用它的父过程。这一次,父过程在头中声明