2

我想在 10gR2 中实现一个堆栈数据结构。

但是,当我尝试这样做时:

创建或替换 TYPE Con​​tainerArray AS VARRAY(25) OF XDB.DBMS_XMLDOM.DOMNODE ;

我明白了

“模式级类型对 XDB.DBMS_XMLDOM 有非法引用。”

所以我发现这是因为 Oracle 不允许您创建引用包级别类型的模式级别类型。

我可以通过在包内创建类型来解决这个问题:

TYPE ContainerArray AS VARRAY(25) OF XDB.DBMS_XMLDOM.DOMNODE;

但是,当我尝试创建我的对象时,我无法引用包级类型:

CREATE TYPE DOMNode_Stack AS OBJECT ( 
   max_size INTEGER, 
   top      INTEGER,
   position ContainerArray,
   MEMBER PROCEDURE initialize,
   MEMBER FUNCTION full RETURN BOOLEAN,
   MEMBER FUNCTION empty RETURN BOOLEAN,
   MEMBER PROCEDURE push (n IN INTEGER),
   MEMBER PROCEDURE pop (n OUT INTEGER)
);

而且我无法在包内创建对象类型,因为我得到了

“在此上下文中不支持对象。”

关于如何解决这个问题的任何想法?

4

1 回答 1

1

像 OBJECT 这样的 sql 级对象只能在其属性中引用 SQL 类型。

如果您看到包装规格:

TYPE DOMNode IS RECORD (id RAW(13));

所以你可以创建一个 sql 数组

SQL> CREATE or replace TYPE ContainerArray AS VARRAY(25) OF raw(13);
  2  /

Type created.

然后在你的对象中

position ContainerArray

这将起作用。当你引用它时,只需分配一个局部变量 v_dom xml_dom.domnode; begin v_dom.id := 您当时正在处理的数组索引值;

请注意,在任何 Oracle 升级中,您都需要验证 DOMNODE 的结构没有改变。

编辑:这是一个示例:

SQL> set serverout on
SQL> create or replace type containerarray as varray(25) of raw(13);
  2  /

Type created.

SQL> create type domnode_stack as object (
  2     position containerarray,
  3     member procedure initialize,
  4     member procedure print_node_names
  5  );
  6  /

Type created.

SQL> CREATE TYPE body DOMNode_Stack
  2  as
  3    member procedure initialize
  4    is
  5      v_dom dbms_xmldom.DOMNode;
  6      v_doc dbms_xmldom.domdocument;
  7      v_nl  dbms_xmldom.DOMNodeList;
  8    begin
  9      position := containerarray();
 10      v_doc := dbms_xmldom.newDOMDocument(xmltype('<root><foo>test</foo><foo2>test2</foo2></root>')); -- just some summy data.
 11      v_nl  := dbms_xmldom.getElementsByTagName(v_doc, '*');
 12      for idx in 0..dbms_xmldom.getLength(v_nl)-1 loop
 13        v_dom := DBMS_XMLDOM.item(v_nl, idx);
 14        position.extend;
 15        position(position.last) := v_dom.id;
 16      end loop;
 17    end;
 18
 19    member procedure print_node_names
 20    is
 21      v_dom dbms_xmldom.DOMNode;
 22    begin
 23      for idx in 1..position.count
 24      loop
 25        v_dom.id := position(idx);
 26        dbms_output.put_line(dbms_xmldom.getnodename(v_dom)||'='||dbms_xmldom.getnodevalue(dbms_xmldom.getfirstchild(v_dom)));
 27      end loop;
 28    end;
 29  end;
 30  /

Type body created.

SQL> show errors type body DOMNode_Stack
No errors.
SQL> declare
  2    o_domnode DOMNode_Stack := DOMNode_Stack(null);
  3  begin
  4    o_domnode.initialize();
  5    o_domnode.print_node_names();
  6  end;
  7  /
root=
foo=test
foo2=test2

PL/SQL procedure successfully completed.

重要的是:

从 DBMS_XMLDOM 分配给我们采用 v_dom.id 的 sql 类型。

13 v_dom := DBMS_XMLDOM.item(v_nl, idx); 14个位置。扩展;15 位置(位置.last):= v_dom.id;

倒车时:

23 for idx in 1..position.count 24 循环 25 v_dom.id := position(idx);

即分配ID部分(不是记录本身..这会出错)回来。

于 2012-11-12T22:06:40.053 回答