2012-02-20 8 views
6

オーバーライドされたPL/SQLメソッドを呼び出す必要があります。ここでは例があります:Oracle 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方法の継承されたバージョンを呼び出したいです。式「SYS_TREAT」を割り当て対象私はローカル変数を使用するときに型本体のコンパイル

として使用することはできません:私はしようとするとtreat(self as test).proc(s);のような明示的なキャストは、それが理由のPLS-00363をコンパイルしません

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)を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; 
/
+1

(TREATはスーパーではなくサブタイプのメソッド/属性にアクセスするために使用されます)私は間違っているかもしれませんが、http://docs.oracle.com/cd/E11882_01/appdev.112/e11822/adobjbas.htm – tbone

+0

はい、そうです。ドキュメントはTREATがサブタイプにしかアクセスできないと言います。しかし、私はどのようにスーパークラスを使うのですか? –

答えて

6

スーパーメソッドにアクセスするには、一般呼び出しまたは一般化式を試してください。例えば、人のスーパータイプと生徒のサブタイプを使用して:

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:

は、10g上にある場合、あなたは少し異なる機能を整理する必要がありますが、子から同じ機能を呼び出すためにスーパー方法:

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; 

学生法のために)(今、あなたは人の方法のために、学生からshow_super()を呼びたい、または単に表示されます。

ドキュメントから、助けてください。

+0

ありがとう、素晴らしい答え。しかし、 "AS"が11gで導入されました。私はそれが10gのための方法がないことを意味すると思います。 –

+0

@ hal9000上記の最新情報を参照 – tbone

関連する問題