我的 Oracle 类型有两个方法,名称为 myType:
create or replace type myType as object (
dummy varchar2(1),
constructor function myType(something varchar2) return self as result,
member procedure mp(self in myType,force boolean := false),
static procedure sp
);
create or replace type body myType is
constructor function myType(something varchar2) return self as result
is
begin
dummy := something;
return;
end;
member procedure mp(self in myType,force boolean := false) is
begin
if self.dummy is null and force then
myType.sp();
end if;
end;
static procedure sp is
begin
null;
end;
end;
这会导致 Oracle 错误:myType 超出范围 (PLS-00225)。如果我删除“myType”。它认为我正在尝试将 sm() 作为成员方法调用,并且还给出了错误(PLS-00587)。
我已经找到了解决问题的方法:
create or replace synonym mySynonym for myType;
然后调用而不是 myType.sp(); -> mySynonym.sp();而且效果很好。
我仍然希望找到一些没有垃圾同义词的解决方案(如果存在的话)。
Oracle版本:11.2
重要:构造函数导致失败,在我的情况下无法消除
抱歉,无法在 Oracle XE 11.2 上重现此问题:
SQL> create or replace type myType as object (
2 z char(1),
3 member procedure mp,
4 static procedure sp
5 );
6 /
Type created.
SQL> create or replace type body myType is
2 member procedure mp is
3 begin
4 myType.sp();
5 end;
6
7 static procedure sp is
8 begin
9 dbms_output.put_line('We''re here');
10 end;
11 end;
12 /
Type body created.
SQL> set serveroutput on
SQL> declare
2 x myType;
3 begin
4 x := myType(z => 'X');
5 x.mp();
6 end;
7 /
We're here
PL/SQL procedure successfully completed.
SQL>
您如何定义类型标头?
编辑:现在您已经添加了构造函数,我可以重现该错误。
解决该问题的一种方法是在调用静态过程时使用架构所有者来限定
myType
:
member procedure mp(self in myType,force boolean := false) is
begin
if self.dummy is null and force then
luke.myType.sp();
end if;
end;
此更改使我能够成功编译类型。
我在以用户
luke
连接到我的 11g XE 数据库时创建了您的过程。 该用户名很可能与您的系统不同。
当然,您的项目可能有不同的开发、测试和生产用户名,因此这可能不是您的理想方法。 如果是这样,创建同义词可能是最好的选择。
也许有人会发现这很有用 - 还有另一种解决方案,不需要同义词或指定类型的模式所有者。使用动态 SQL(例如
execute immediate
)可以实现这一点。但要小心 - execute immediate
强制 - 至少 - 软解析,如果频繁进行该调用,这将使您的代码变慢。
这是一个示例(基于 smnbbrv 代码):
create or replace type myType as object (
dummy varchar2(4000),
constructor function myType(something varchar2) return self as result,
member procedure mp(self in myType,force boolean := false),
static procedure sp
);
/
create or replace type body myType is
constructor function myType(something varchar2) return self as result
is
begin
dummy := something;
return;
end;
member procedure mp(self in myType,force boolean := false) is
begin
if self.dummy is null and force then
execute immediate 'CALL myType.sp()';
end if;
end;
static procedure sp is
begin
dbms_output.put_line('Call to myType.sp');
end;
end;
/
测试:
set serveroutput on;
declare
v_x myType := myType(something => null);
begin
v_x.mp(force => True);
end;
/
-- Result printed to output:
Call to myType.sp
PL/SQL procedure successfully completed.