为什么我得到 PLS-00302:组件存在时必须声明?
Why do I get PLS-00302: component must be declared when it exists?
我正在使用 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;
/
如果我在没有架构的情况下使用 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: component 'MY_FUNC2' must be declared
我不明白为什么会出现此错误,当我的函数在另一个模式 (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
时,不会造成混淆,因此可以正常工作。
文档explains name resolution。限定对象名称的第一部分 - 此处为 S2 - 在被评估为不同的模式之前被评估为当前模式上的对象。
这可能不是一个序列;其他对象可能会导致相同的错误。您可以通过查询数据字典来检查是否存在同名对象。
select owner, object_type, object_name
from all_objects
where object_name = 'S2';
我来这里是因为我遇到了同样的问题。
对我来说问题是程序是在包体中定义的,而不是在包头中。
我在执行我的函数时使用了一个 lose BEGIN END 语句。
我正在使用 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;
/
如果我在没有架构的情况下使用 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: component 'MY_FUNC2' must be declared
我不明白为什么会出现此错误,当我的函数在另一个模式 (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
时,不会造成混淆,因此可以正常工作。
文档explains name resolution。限定对象名称的第一部分 - 此处为 S2 - 在被评估为不同的模式之前被评估为当前模式上的对象。
这可能不是一个序列;其他对象可能会导致相同的错误。您可以通过查询数据字典来检查是否存在同名对象。
select owner, object_type, object_name
from all_objects
where object_name = 'S2';
我来这里是因为我遇到了同样的问题。
对我来说问题是程序是在包体中定义的,而不是在包头中。
我在执行我的函数时使用了一个 lose BEGIN END 语句。