如何在Oracle 11g R2的内存中创建递归对象并将其存储在数据库

时间:2016-09-07 21:54:25

标签: oracle object recursion oracle11g

我有这段代码片段在数据库中存储表达式,让我们称之为example1:

create or replace type expression as object 
(
  type varchar2(400),
  MEMBER FUNCTION eval RETURN number
)NOT INSTANTIABLE NOT FINAL;

create or replace type mutiplication under expression
(
  leftexpr ref expression,
  rightexpr ref expression,
  STATIC FUNCTION createMultiplication (leftexpr ref expression, rightexpr ref expression) return ref expression,
  OVERRIDING MEMBER FUNCTION eval RETURN NUMBER
);

但是,我并不想将所有子表达式存储在数据库中以便能够构建对象,因此我尝试使用此代码,让我们将其称为example2:

create or replace type expression as object 
(
  type varchar2(400),
  MEMBER FUNCTION eval RETURN number
)NOT INSTANTIABLE NOT FINAL;

create or replace type mutiplication under expression
(
  leftexpr expression,
  rightexpr expression,
  STATIC FUNCTION createMultiplication (leftexpr expression, rightexpr expression) return expression,
  OVERRIDING MEMBER FUNCTION eval RETURN NUMBER
);

首先,我甚至没有尝试使用example2代码,因为我认为它不起作用,因为当我尝试使用这样的类型时:

create or replace type expression as object 
(
  type varchar2(400),
  leftexpr expression,
  rightexpr expression,
  MEMBER FUNCTION eval RETURN number
);
/

我收到此错误消息:

Oracle错误:PLS-00318 错误描述: 输入"表达"格式错误,因为它是非REF相互递归类型;

当我真正尝试代码并创建了一个表格,如:

CREATE TABLE expression_table OF expression;

我收到以下错误:

Error: ORA-30756 "cannot create column or table of type that contains a supertype attribute" 
Cause: 
The user tried to create a column or table of an object type that contains a supertype attribute. This is not supported because it leads to infinite recursion in our current storage model. Note that creating a column of a type implies that we create columns corresponding to all subtype attributes as well.

所以我现在正在做的是将example1和example2结合起来,以便能够在内存中创建递归对象,然后再存储它并能够检索它。 这有什么不那么乏味的事吗? 这是我现在使用的代码:

DROP TABLE expression_table;
DROP TYPE BODY SIMPLEN_SAVE;
DROP TYPE BODY MULTIPLICATION_SAVE;
DROP TYPE SIMPLEN_SAVE;
DROP TYPE MULTIPLICATION_SAVE;
DROP TYPE EXPRESSION_SAVE;
DROP TYPE BODY SIMPLEN;
DROP TYPE SIMPLEN;
DROP TYPE BODY MULTIPLICATION;
DROP TYPE MULTIPLICATION;
DROP TYPE EXPRESSION;


create or replace type expression_save as object 
(
  type varchar2(400),
  MEMBER FUNCTION eval RETURN number
)NOT INSTANTIABLE NOT FINAL;
/

create or replace type multiplication_save under expression_save
(
  leftexpr ref expression_save,
  rightexpr ref expression_save,
  STATIC FUNCTION CRT(p_leftexpr ref expression_save, p_rightexpr ref expression_save) return ref expression_save
);
/
create or replace type SIMPLEN_SAVE under expression_save
(
  datan number,
  STATIC FUNCTION CRT(p_datan in number) return ref expression_save
);
/

CREATE TABLE expression_table OF expression_save
OBJECT IDENTIFIER IS SYSTEM GENERATED;
/

create or replace
type body multiplication_save as
  STATIC FUNCTION CRT(p_leftexpr ref expression_save, p_rightexpr ref expression_save) return ref expression_save is
    ret ref expression_save;
    inst expression_save;
    rid rowid;
  begin
    inst := MULTIPLICATION_SAVE('MULTIPLICATION',p_leftexpr,p_rightexpr);

    insert into expression_table values(inst) returning rowid into rid;
    select ref(s) into ret from expression_table s where rowid = rid;
    return ret;
  end;
end;
/

create or replace type body SIMPLEN_SAVE as
  STATIC FUNCTION CRT(p_datan in number) return ref expression_save is
    ret ref expression_save;
    inst expression_save;
    rid rowid;
  begin
    inst := SIMPLEN_SAVE('SIMPLEN',p_datan);

    insert into expression_table values(inst) returning rowid into rid;
    select ref(s) into ret from expression_table s where rowid = rid;

    return ret;
  end;
end;
/

create or replace function LOADEXPRESSION(ref expression_save) return expression is
  expr_save expression_save;
  begin
    select deref(expression_save) into expr_save from dual;
    if(expr_save.type = 'MULTIPLICATION')then
      return MULTIPLICATION('MULTIPLICATION',expression.LOAD((expr_save AS multiplication_save).leftexpr),expression.LOAD((expr_save AS multiplication_save).rightexpr));
    end if;

    if(expr_save.type = 'SIMPLEN')then
      return MULTIPLICATION('SIMPLEN',(expr_save AS multiplication_save).data);
    end if;

  end;
/

create or replace type expression as object 
(
  type varchar2(400),
  MEMBER FUNCTION eval RETURN number,
  MEMBER FUNCTION SAVE return ref expression_save
)NOT INSTANTIABLE NOT FINAL;
/

create or replace type mutiplication under expression
(
  leftexpr expression,
  rightexpr expression,
  STATIC FUNCTION CRT(p_leftexpr expression, p_rightexpr expression) return expression,
  OVERRIDING MEMBER FUNCTION eval RETURN NUMBER,
  OVERRIDING MEMBER FUNCTION SAVE RETURN ref expression_save
);
/

create or replace type body mutiplication as
  STATIC FUNCTION CRT(p_leftexpr expression, p_rightexpr expression) return expression is
  begin
    return mutiplication('MULTIPLICATION',p_leftexpr,p_rightexpr);
  end;
  OVERRIDING MEMBER FUNCTION eval RETURN NUMBER is
  begin
    return leftexpr.eval * rightexpr.eval;
  end;
  OVERRIDING MEMBER FUNCTION SAVE RETURN ref expression_save is
  begin
    return multiplication_save.crt(leftexpr.save, rightexpr.save);
  end;
end;
/

create or replace type simplen under expression
(
  data number,
  STATIC FUNCTION CRT(data number) return expression,
  OVERRIDING MEMBER FUNCTION eval RETURN NUMBER,
  OVERRIDING MEMBER FUNCTION SAVE RETURN ref expression_save
);
/

create or replace type body simplen as
  STATIC FUNCTION CRT(data number) return expression is
  begin
    return simplen('SIMPLEN',data);
  end;
  OVERRIDING MEMBER FUNCTION eval RETURN NUMBER is
  begin
    return data;
  end;
  OVERRIDING MEMBER FUNCTION SAVE RETURN ref expression_save is
  begin
    return simplen_save.crt(data);
  end;
end;
/

1 个答案:

答案 0 :(得分:0)

这两个班级之间有什么关系?您指出multiplication应该覆盖eval方法,但您没有指出multiplication应该从其他类继承,因此没有eval方法可以覆盖。

如果您打算让multiplication成为expression的孩子,那么您需要under条款

create or replace type mutiplication2 
  under expression
(
  leftexpr expression,
  rightexpr expression,
  STATIC FUNCTION createMultiplication (leftexpr expression, rightexpr expression) return expression,
  OVERRIDING MEMBER FUNCTION eval RETURN NUMBER
);
/

如果您希望multiplication成为没有继承的第一级对象,那么在定义成员函数时不会使用overriding子句

create or replace type mutiplication as object
(
  leftexpr expression,
  rightexpr expression,
  STATIC FUNCTION createMultiplication (leftexpr expression, rightexpr expression) return expression,
  MEMBER FUNCTION eval RETURN NUMBER
);
/