2014-04-25 19 views
7

Muszę zdefiniować typ obiektu Pracownik, który będzie posiadał pewne atrybuty, następnie muszę zdefiniować typ obiektu Menedżer, który odziedziczy typ Pracownik i będzie miał atrybut dodatkowy o nazwie nrEmp, który będzie zawierał liczbę pracowników, których każdy menedżer ma pod jego dowództwem. Muszę również wdrożyć metodę ORDER dla menedżera typu, dzięki czemu mogę zamówić menedżerów według liczby posiadanych przez nich pracowników. Najpierw definiuje ten typ:Jak przesłonić metodę ZAMÓWIENIA PL/SQL?

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

Następne I zdefiniowany typ Pracownik:

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

wszystko działało dobrze aż do teraz. Następne próbuję zdefiniować typ Manager:

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

Kiedy zrobić to pojawia się następujący błąd:

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

jak rozumiem muszę zadeklarować metodę w rodzaju pracownika. Ale nie jestem pewien, jak to zrobić we właściwy sposób. Nie można znaleźć żadnego przykładu pokazującego, jak zaimplementować metodę ORDER podczas dziedziczenia. Każda pomoc będzie doceniona. Dziękuję Ci.

+0

Instrukcja może pomóc: http://docs.oracle.com/cd/E11882_01/appdev.112/e11822/adobjbas.htm#sthref161 –

Odpowiedz

4

Znalazłem sposób na zrobienie tego. Nie mogę powiedzieć, że jest to najlepsze rozwiązanie lub najbardziej elegancka, ale działa dobrze na moje potrzeby. Oto kod. Typ Pracownik:

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; 

typ Manager:

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

Ciało na typ Employee:

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; 

To wszystko, co musisz zrobić, jeśli chcesz porównać 2 obiekty Manager. Metoda ORDER wykona rzutowanie typu od typu Pracownik do Menedżera. Na przykład:

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; 

Nie zapomnij ustawić wyjścia przed powyższym blokiem kodu, aby zobaczyć wyświetlany wynik.

SET SERVEROUTPUT ON; 
+0

dziękuję za pytanie i odpowiedź – NASRIN

1

miałem tylko do rozwiązania tego samego problemu i cam się z następującym roztworem:

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

Pozwala nadrzędnych funkcji zlecenia/map nadrzędnymi zwane funkcje.

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; 
Powiązane problemy