How to override ORDER method PL/SQL? How to override ORDER method PL/SQL? oracle oracle

How to override ORDER method PL/SQL?


I found a way to do this. I can't say this is the best solution or the most elegant one, but it worked fine for my needs. Here is the code.Employee type:

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;

Manager type:

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

The body for Employee type:

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;

That is all you have to do if you want to compare 2 Manager objects. The ORDER method will do a type casting from Employee to Manager type. For example:

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;

Don't forget to set the output on before the above block of code, so you can see the displayed result.

SET SERVEROUTPUT ON;


I just had to solve the same issue and cam up with following solution:

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

This allows overriding of order/map functions by overriding called functions.

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