2014-04-25 12 views
7

Devo definire un tipo di oggetto Dipendente che avrà alcuni attributi, quindi devo definire un tipo di oggetto Manager che erediterà il tipo Employee e avrò un attributo adizionale chiamato nrEmp che conterrà il numero di dipendenti che ogni manager ha sotto il suo comando. Inoltre devo implementare il metodo ORDER per il tipo Manager, quindi posso ordinare i manager in base al numero di dipendenti che hanno. In primo luogo ho definito questo tipo:Come sovrascrivere il metodo ORDER PL/SQL?

CREATE OR REPLACE TYPE Departament AS OBJECT ( 
    deptno NUMBER(2), 
    dname CHAR(14) 
    ); 

Next i definito il tipo di organigramma:

CREATE OR REPLACE TYPE Employee AS OBJECT ( 
    empno NUMBER(4), 
    ename CHAR(10), 
    dept REF Departament, 
    sal NUMBER(7,2) 
    ) NOT FINAL; 

Tutto ha funzionato bene fino ad ora. Successivo cerco di definire il tipo di manager:

CREATE OR REPLACE TYPE Manager UNDER Employee (
    nrEmp INTEGER, 
    ORDER MEMBER FUNCTION compare(m Manager) RETURN INTEGER 
); 

Quando faccio questo io ottenere il seguente errore:

Error(1,1): PLS-00646: MAP or ORDER method must be defined in the root of the subtype hierarchy 

a quanto ho capito devo dichiarare il metodo nel tipo Employee. Ma non sono sicuro di come farlo nel modo giusto. Non ho trovato alcun esempio che mostra come implementare il metodo ORDER quando si eredita. Qualsiasi aiuto sarebbe apprezzato. Grazie.

+0

Il manuale potrebbe aiutare: http://docs.oracle.com/cd/E11882_01/appdev.112/e11822/adobjbas.htm#sthref161 –

risposta

4

Ho trovato un modo per farlo. Non posso dire che questa sia la soluzione migliore o la più elegante, ma ha funzionato bene per i miei bisogni. Ecco il codice. Tipo Employee:

CREATE OR REPLACE TYPE Employee AS OBJECT ( 
    empno NUMBER(4), 
    ename CHAR(10), 
    dept REF Departament, 
    sal NUMBER(7,2), 
    ORDER MEMBER FUNCTION match (other IN Employee) RETURN INTEGER 
    ) NOT FINAL; 

digitare Gestione:

CREATE OR REPLACE TYPE Manager UNDER Employee (
    nrEmp INTEGER 
); 

Il corpo Inquadramento:

CREATE OR REPLACE TYPE BODY Employee AS 
    ORDER MEMBER FUNCTION match(other IN Employee) Return INTEGER IS 
    v_mng_self Manager; 
    v_mng_other Manager; 
    BEGIN 
     v_mng_self := TREAT(self AS Manager); 
     v_mng_other := TREAT(other AS Manager); 
     IF v_mng_self.nrEmp < v_mng_other.nrEmp THEN 
     RETURN -1; 
     ELSIF v_mng_self.nrEmp > v_mng_other.nrEmp THEN 
     RETURN 1; 
     ELSE 
     RETURN 0; 
     END IF; 
    END; 
END; 

Questo è tutto quello che devi fare se si vuole confrontare 2 oggetti Manager. Il metodo ORDER eseguirà un casting di tipo da Employee a Manager. Ad esempio:

DECLARE 
    manager1 Manager; 
    manager2 Manager; 
BEGIN 
    manager1 := Manager(7823,'John',null,2000,10); 
    manager2 := Manager(7782,'Bob',null,3000,15); 
    IF manager1 < manager2 THEN 
    SYS.DBMS_OUTPUT.PUT_LINE('manager1 has less employees than manager2'); 
    END IF; 
END; 

Non dimenticare di impostare l'uscita prima del blocco di codice precedente, in modo da poter visualizzare il risultato visualizzato.

SET SERVEROUTPUT ON; 
+0

grazie per la vostra domanda e risposta – NASRIN

1

Ho appena avuto per risolvere lo stesso problema e Cam con seguente soluzione:

create or replace type employee as object(
    empno number(4), 
    member function compare_internal(e employee) return integer, 
    order member function compare(e employee) return integer 
) not final; 
/

create or replace type body employee is 
    member function compare_internal(e employee) return integer is 
     begin 
     return 
      case 
      when self.empno = e.empno then 0 
      when self.empno > e.empno then 1 
      when self.empno < e.empno then -1 
      end; 
     end; 

    order member function compare(e employee) return integer is 
     begin 
     return compare_internal(e); 
     end; 
end; 
/

create or replace type manager under employee( 
    nr_emp integer, 
    overriding member function compare_internal(e employee) 
    return integer); 
/

create or replace type body manager is 
    overriding member function compare_internal(e employee) return integer is 
     m manager; 
     r integer; 
     begin 
     if e is of (manager) then 
      m := treat(e as manager); 
      r := 
       case 
        when self.nr_emp = m.nr_emp then 0 
        when self.nr_emp > m.nr_emp then 1 
        when self.nr_emp < m.nr_emp then -1 
       end; 
     end if; 
     return r; 
     end; 
end; 
/

Questo permette prioritario di funzioni di ordine/mappa sovrascrivendo funzioni chiamate.

declare 
    x employee; 
    y employee; 
begin 
    x := employee(empno => 1); 
    y := employee(empno => 1); 
    dbms_output.put_line(x.compare(y)); 
    -- gives 0, as both have same empno 

    x := manager(empno => 1, nr_emp => 2); 
    y := manager(empno => 1, nr_emp => 3); 
    dbms_output.put_line(x.compare(y)); 
    -- gives -1 as both have different nr_emp 

    x := employee(empno => 1); 
    y := manager(empno => 1, nr_emp => 3); 
    dbms_output.put_line(x.compare(y)); 
    -- gives 0, as both have same empno -- is that what we want? 

    x := manager(empno => 1, nr_emp => 3); 
    y := employee(empno => 1); 

    dbms_output.put_line(x.compare(y)); 
    -- gives null, y is not a manager 

end;