2015-12-10 9 views
2

Я создал следующий тест, чтобы продемонстрировать мою проблему:Как я могу вставить несколько узлов xml с XMLQuery (XQuery) в Oracle SQL?

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. 

Я считаю, что проблема связана с тем, что я вставив несколько узлов идентификаторов, как это будет работать, если у меня есть только один в таблице, но я не Не понимаю, почему appendChildXML будет работать, а XMLQuery не будет.

Я предполагаю, возможно, мне нужно использовать выражение FLWOR, но я не смог создать тот, который работает.

В настоящее время я использую Oracle 11g и буду перемещаться в 12c (пытаясь перейти к XMLQuery, поскольку appendChildXML устарел в 12c). У меня мало опыта работы с XML в Oracle и без предшествующего опыта XMLQuery.

Может ли кто-нибудь предложить совет о том, как заставить XMLQuery работать? Благодаря!

ответ

0

Я был в состоянии получить результаты, мне нужно с помощью следующего запроса , Спасибо Франсиско Ситя за его ответ и выражение 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

Вы можете использовать ор: функцию просмотра, чтобы запросить таблицу, а затем генерировать XML с выражением FLWOR, что-то вроде этого:

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

Существующий узел инвентаря будет располагаться в таблице в реальной реализации, и это будет использоваться в заявлении об обновлении. Я смог воспроизвести это в тесте select select, просто предоставив ему пустой инвентарь. Еще раз спасибо! – DBox