2015-12-10 101 views
2

我已經創建了下面的測試案例來證明我的問題:如何在Oracle SQL中使用XMLQuery(XQuery)插入多個XML節點?

create table test_table (idx number, a varchar2(20), b varchar2(20)); 
insert into test_table values (1, 'item1', 'value1'); 
insert into test_table values (2, 'item2', 'value2'); 

select appendChildXML(
         xmltype('<inventory></inventory>'), 
         '/inventory', 
         xmlagg(
          xmlelement("id", xmlattributes(tt.idx as "val"), 
          xmlelement("listing", 
           xmlelement("item",tt.a), 
           xmlelement("value",tt.b) 
         )))) as xml 
from test_table tt 
; 

這給出了所需的輸出:

<inventory> 
    <id val="1"> 
    <listing> 
     <item>item1</item> 
     <value>value1</value> 
    </listing> 
    </id> 
    <id val="2"> 
    <listing> 
     <item>item2</item> 
     <value>value2</value> 
    </listing> 
    </id> 
</inventory> 

但是,如果我嘗試使用XMLQuery我得到一個錯誤。

select XMLQuery(
        (
        'copy $tmp := . modify insert node ' 
        || xmlagg(
          xmlelement("id", xmlattributes(tt.idx as "val"), 
          xmlelement("listing", 
           xmlelement("item",tt.a), 
           xmlelement("value",tt.b) 
         ))) 
        || ' as last into $tmp/inventory return $tmp' 
       ) 
        PASSING xmltype('<inventory></inventory>') RETURNING CONTENT 
       ) as xml 
from test_table tt 
; 

錯誤:

ORA-19112: error raised during evaluation: 
XVM-01003: [XPST0003] Syntax error at 'id' 
1 copy $tmp := . modify insert node <id val="1"><listing><item>item1</item><v 
-                            ^

19112. 00000 - "error raised during evaluation: %s" 
*Cause: The error function was called during evaluation of the XQuery expression. 
*Action: Check the detailed error message for the possible causes. 

我相信問題與事實,我插入多個ID節點,因爲它會工作,如果我只有一個表中的事,但我不不明白爲什麼appendChildXML會起作用,XMLQuery不會。

我猜可能我需要使用FLWOR表達式,但我一直無法創建一個工作。

我目前正在使用Oracle 11g,並將轉移到12c(嘗試遷移到XMLQuery,因爲appendChildXML在12c中已棄用)。我幾乎沒有使用過Oracle的XML經驗,也沒有以前的XMLQuery經驗。

任何人都可以提供關於如何讓XMLQuery工作的建議嗎?謝謝!

回答

0

我能得到我通過下面的查詢所需的結果。感謝Francisco Sitja的回答和FLWOR表達,這引導我走向完整的答案。

select XMLQuery(
        (
        'copy $tmp := . modify insert node ' 
        || 'for $i in ora:view("TEST_TABLE") 
          let $idval := $i/ROW/IDX, 
           $item := $i/ROW/A/text(), 
           $value := $i/ROW/B/text() 
         return <id val="{$idval}"> 
            <listing> 
            <item>{$item}</item> 
            <value>{$value}</value> 
            </listing> 
           </id>' 
        || ' as last into $tmp/inventory return $tmp' 
       ) 
        PASSING xmltype('<inventory></inventory>') RETURNING CONTENT 
       ) as xml 
from dual; 
0

可以使用ORA:視圖功能來查詢表,然後生成FLWOR表達式的XML,像這樣:

10/12/2015 19:53:25:SQL> SELECT XMLQuery('<inventory> 
    2     {for $i in ora:view("TEST_TABLE") 
    3      let $idval := $i/ROW/IDX, 
    4       $item := $i/ROW/A/text(), 
    5       $value := $i/ROW/B/text() 
    6      return <id val="{$idval}"> 
    7        <listing> 
    8         <item>{$item}</item> 
    9         <value>{$value}</value> 
10        </listing> 
11        </id>} 
12     </inventory>' 
13     RETURNING CONTENT) AS test_xml 
14 FROM DUAL; 

TEST_XML 
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
<inventory><id val="1"><listing><item>item1</item><value>value1</value></listing></id><id val="2"><listing><item>item2</item><value>value2</value></listing></id></inventory> 
+0

現有庫存節點位於何處(文件,表格,變量)?我們如何獲得它與新的ID子節點「合併」? –

+0

現有庫存節點將位於實際實施中的表中,並將用於更新聲明中。通過給它一個空白庫存節點,我能夠在測試選擇語句中模仿它。再次感謝! – DBox