How to call Oracle PL / SQL supercomponent method

I would like to call an overridden PL / SQL method. Here is an example:

-- 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) ) / 

Now I want to call the inherited version of the proc method. When I try to do an explicit conversion, for example treat(self as test).proc(s); , it will not compile due to PLS-00363: the expression 'SYS_TREAT' cannot be used as the destination

The type body compiles when I use a local variable:

 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; / 

But when I run my example like this

 declare obj test2; begin obj := test2(0); obj.proc('1'); end; 

... he throws out ORA-21780: The maximum number of object durations has been exceeded.

Is there a way to call test :: proc (without serialization / deserialization)?

And ... after calling proc, how can I change any changed attributes (namely n ) in obj ?


Update (Thanks, tbone):

I changed the organization of my methods using template methods ("before" and "after"). I add them when I need to extend the method.

 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; / 
+6
source share
1 answer

To access super-methods, try either a generic call or a generic expression. For example, using a person’s supertype and student subtype:

 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; 

EDIT:

If you are on 10g, you will need to organize the functions a little different, but with the same functionality from the child, to call the super method:

 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; 

Now you call show_super () from the student for the person method or just show () for the student method.

From the docs, hope this helps.

+6
source

Source: https://habr.com/ru/post/908898/


All Articles