我必须定义一个具有一些属性的对象类型Employee,然后我必须定义一个将继承Employee类型的对象类型Manager,并且将有一个名为nrEmp的aditional属性,它将包含每个manager的员工数量在他的指挥下。此外,我必须为类型管理器实现方法ORDER,因此我可以按照他们拥有的员工数量来命令管理员。首先我定义了这种类型:
CREATE OR REPLACE TYPE Departament AS OBJECT (
deptno NUMBER(2),
dname CHAR(14)
);
接下来我定义了Employee类型:
CREATE OR REPLACE TYPE Employee AS OBJECT (
empno NUMBER(4),
ename CHAR(10),
dept REF Departament,
sal NUMBER(7,2)
) NOT FINAL;
到目前为止,一切都运转正常。接下来我尝试定义类型管理器:
CREATE OR REPLACE TYPE Manager UNDER Employee (
nrEmp INTEGER,
ORDER MEMBER FUNCTION compare(m Manager) RETURN INTEGER
);
当我这样做时,我收到以下错误:
Error(1,1): PLS-00646: MAP or ORDER method must be defined in the root of the subtype hierarchy
据我所知,我必须在Employee类型中声明该方法。但我不确定如何以正确的方式做到这一点。无法找到任何显示如何在继承时实现ORDER方法的示例。任何帮助,将不胜感激。谢谢。
答案 0 :(得分:4)
我找到了一种方法来做到这一点。我不能说这是最好的解决方案或最优雅的解决方案,但它可以满足我的需求。这是代码。 员工类型:
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;
经理类型:
CREATE OR REPLACE TYPE Manager UNDER Employee (
nrEmp INTEGER
);
员工类型的正文:
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;
如果您想比较2个Manager对象,那就是您需要做的全部工作。 ORDER方法将执行从Employee到Manager类型的类型转换。例如:
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;
不要忘记在上面的代码块之前设置输出,这样就可以看到显示的结果。
SET SERVEROUTPUT ON;
答案 1 :(得分:1)
我只需要解决同样的问题并提出以下解决方案:
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;
/
这允许通过覆盖被调用函数来覆盖order / map函数。
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;