2012-11-12 51 views
1

我想在10gR2中實現一個堆棧數據結構。Oracle:在包中創建一個對象類型數組

但是,當我嘗試做:

創建或替換TYPE Con​​tainerArray AS VARRAY(25)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) 
); 

,我不能創建包內的對象類型,因爲我得到

「對象不在此CON支持文本。」

有關如何解決此問題的任何想法?

回答

1

像OBJECT這樣的sql級別對象只能在其屬性中引用SQL類型。

,如果你看到包裝規格:

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

,所以你可以創建

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

Type created. 

一個SQL數組,那麼在你的對象放在

position ContainerArray 

這將正常工作。當你引用它時,只需分配一個局部變量 v_dom xml_dom.domnode; 開始 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 position.extend; 15 position(position.last):= v_dom。ID;

和倒車時:

23,用於在IDX 1..position.count 24環 25 v_dom.id:=位置(IDX);

即分配ID部分(不是記錄本身......這將錯誤)回來。

+0

感謝您的回覆。我能夠獲得創建的對象。現在我遇到的一個問題是在類型之間進行轉換。例如,當調用my_stack.push(my_node)時,我得到'錯誤的數量或類型的參數',因爲push被定義爲採用RAW,my_node是DOMNODE。但DOMNODE實際上是一個RAW(13)。我如何讓Oracle允許交換使用這些類型? CAST()不會像它會起作用。 – wadesworld

+0

創建一個局部變量,如:'v_dom DBMS_XMLDOM.DOMNode'然後像'v_dom.id:= t_array(idx)'(其中t_array是你的sql數組,idx是當時處理的數組元素)一樣分配。 – DazzaL

+0

不幸運。 '表達式是錯誤的類型'我想知道如果我將不得不使用SQL從這個VARRAY插入和刪除元素。 – wadesworld

相關問題