gpt4 book ai didi

oracle - 如何调用 Oracle PL/SQL 对象 super 方法

转载 作者:行者123 更新时间:2023-12-04 14:49:26 26 4
gpt4 key购买 nike

我想调用一个重写的 PL/SQL 方法。下面是一个例子:

-- super class
create or replace type test as object
(
n number,
member procedure proc(SELF in out nocopy test, s varchar2)
)
alter type test not final
/

create or replace type body test is
member procedure proc(SELF in out nocopy test, s varchar2) is
begin
dbms_output.put_line('test1: n='||nvl(self.n, 'null')||' s='||s);
self.n := to_number(s);
end;
end;
/

-- derived class
create or replace type test2 under test
(
overriding member procedure proc(SELF in out nocopy test2, s varchar2)
)
/

现在我想调用 proc 的继承版本方法。当我尝试执行像 treat(self as test).proc(s); 这样的显式转换时它不会编译因为 PLS-00363:表达式“SYS_TREAT”不能用作赋值目标

当我使用局部变量时,类型主体会编译:
create or replace type body test2 is
overriding member procedure proc(SELF in out nocopy test2, s varchar2) is
O test;
begin
O := treat(self as test);
O.proc(s);
end;
end;
/

但是当我像这样运行我的例子时
declare
obj test2;
begin
obj := test2(0);
obj.proc('1');
end;

...它抛出 ORA-21780: 超出了对象持续时间的最大数量。

有没有办法调用 test::proc (没有序列化/反序列化)?

并且...在调用 proc 之后,如何将任何更改的属性(即 n )反射(reflect)在 obj 中?

更新 (谢谢,tbone):

我使用模板方法(“之前”和“之后”)更改了我的方法的组织。每当我需要扩展方法时,我都会添加它们。
create or replace type test as object
(
n number,
member procedure proc (SELF in out nocopy test, s varchar2),
member procedure afterProc (SELF in out nocopy test, s varchar2)
member procedure beforeProc(SELF in out nocopy test, s varchar2),
)
not final
/

create or replace type body test is
member procedure proc(SELF in out nocopy test, s varchar2) is
begin
beforeProc(s);
dbms_output.put_line('test1: n='||nvl(n, 'null')||' s='||s);
n := to_number(s);
afterProc(s);
end;
member procedure afterProc (SELF in out nocopy test, s varchar2) is begin null; end;
member procedure beforeProc(SELF in out nocopy test, s varchar2) is begin null; end;
end;
/

最佳答案

要访问 super 方法,请尝试通用调用或通用表达式。例如,使用个人父类(super class)型和学生子类型:

CREATE OR REPLACE TYPE person_typ AS OBJECT (
idno number,
name varchar2(30),
phone varchar2(20),
MAP MEMBER FUNCTION get_idno RETURN NUMBER,
MEMBER FUNCTION show RETURN VARCHAR2)
NOT FINAL;

CREATE OR REPLACE TYPE BODY person_typ AS
MAP MEMBER FUNCTION get_idno RETURN NUMBER IS
BEGIN
RETURN idno;
END;
MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
-- function that can be overriden by subtypes MEMBER FUNCTION show RETURN VARCHAR2 IS BEGIN
RETURN 'Id: ' || TO_CHAR(idno) || ', Name: ' || name;
END;
END;

CREATE TYPE student_typ UNDER person_typ (
dept_id NUMBER,
major VARCHAR2(30),
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2)
NOT FINAL;

CREATE TYPE BODY student_typ AS
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
RETURN (self AS person_typ).show || ' -- Major: ' || major ;
END;
END;

-- Using Generalized Invocation
DECLARE
myvar student_typ := student_typ(100, 'Sam', '6505556666', 100, 'Math');
name VARCHAR2(100);
BEGIN
name := (myvar AS person_typ).show; --Generalized invocation
END;

-- Using Generalized Expression
DECLARE
myvar2 student_typ := student_typ(101, 'Sam', '6505556666', 100, 'Math');
name2 VARCHAR2(100);
BEGIN
name2 := person_typ.show((myvar2 AS person_typ)); -- Generalized expression
END;

编辑:

如果您使用的是 10g,则需要对函数进行一些不同的组织,但与调用 super 方法的子函数具有相同的功能:
CREATE TYPE BODY person_typ AS 
MAP MEMBER FUNCTION get_idno RETURN NUMBER IS
BEGIN
RETURN idno;
END;
-- static function that can be called by subtypes
STATIC FUNCTION show_super (person_obj in person_typ) RETURN VARCHAR2 IS
BEGIN
RETURN 'Id: ' || TO_CHAR(person_obj.idno) || ', Name: ' || person_obj.name;
END;
-- function that can be overriden by subtypes
MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
RETURN person_typ.show_super ( SELF );
END;
END;

CREATE TYPE student_typ UNDER person_typ (
dept_id NUMBER,
major VARCHAR2(30),
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2)
NOT FINAL;

CREATE TYPE BODY student_typ AS
OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS
BEGIN
RETURN person_typ.show_super ( SELF ) || ' -- Major: ' || major ;
END;
END;

现在你可以从 student 方法中调用 show_super() 来调用 person 方法,或者只调用 show() 来调用 student 方法。

从文档中,希望有所帮助。

关于oracle - 如何调用 Oracle PL/SQL 对象 super 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9362994/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com