XML直接通过查询ORACLE db

时间:2014-09-13 11:12:20

标签: sql xml oracle plsql schema

我正在查询Oracle数据库,使用XMLELEMENT和XMLFOREST从每行中生成XML。 对于单表,它工作正常。但我的要求是从3个不同的表中获取数据。

描述:

Table Main,SecondTable,ThirdTable。其中Main和SecondTable具有唯一的TxnID,而在ThirdTable中则重复。

示例:

 Main Table                        SecondTable                      ThirdTable

TxnId  A   B   C             D    TxnId   E    F                  G    H   I   TxnId

1001   3   4   6             5    1001    6    2                  2    5   5    1001
1002   5   6   2             4    1002    5    6                  6    8   9    1001
1003   5   4   2             6    1003    5    6                  8    9   8    1001

我想用XML重复发布这些数据,到目前为止我能够以XML格式获得第一行,

Select XMLELELEMENT(("Event", XMLFOREST(m.A as 'A',
                                        m.B as 'B',
                                        m.C as 'C') ||
                              XMLELEMENT("SecondTable",
                                         XMLFOREST(s.E as 'E',
                                                   s.F as 'F')) ||
                              XMLELEMENT("ThirdTable",
                                         XMLFOREST(t.G as 'G',
                                                   t.H as 'H',
                                                   t.I as 'I')))
  from Main m
  JOIN SecondTable s
    ON m.TxnId=s.TxnId
  JOIN ThirdTable t
    ON s.TxnId=t.TxnId

此查询将为我提供类似 -

的输出
<Event>
   <Main>
      <A>3</A>
      <B>4</B>
      <C>6</C>
   </Main>
  <SecondTable>
      <E>6</E>
      <F>2</F>
  </SecondTable>
       <ThirdTable>
             <G>2</G>
             <H>5</H>
             <I>5</I>
       </ThirdTable>
 </Event>

问题:我希望重复使用ThirdTable的TxnIds在一个XML中形成3个块。我希望我很清楚。 请帮我。 在此先感谢。

1 个答案:

答案 0 :(得分:0)

您可以使用xmlagg函数和group by子句来实现此目的。我还包括了对ThirdTable的外部加入。请参阅下面的解决方案,希望这会有所帮助:

场景设置:

            create table main 
            (txnid number(4),a VARCHAR2(1), b VARCHAR2(1), c VARCHAR2(1));

            insert into main values (1001, 3 ,4 ,6);
            insert into main values (1002, 5 ,6 ,2);
            insert into main values (1003, 5 ,4 ,2);

            create table secondtable 
            (d VARCHAR2(1),txnid number(4), e VARCHAR2(1), f VARCHAR2(1));

            insert into secondtable values (5, 1001 ,6 ,2);
            insert into secondtable values (4, 1002 ,5 ,6);
            insert into secondtable values (6, 1003 ,5 ,6);

            create table thirdtable 
            (g VARCHAR2(1), h VARCHAR2(1), i VARCHAR2(1), txnid number(4));


            insert into thirdtable  values (2, 5 ,5 ,1001);
            insert into thirdtable  values (6, 8 ,9 ,1001);
            insert into thirdtable  values (8, 9 ,8 ,1001);

            commit;

查询:

            select XMLELEMENT("Event", xmlelement("Main", 
                                          XMLFOREST(m.A as "A",
                                                    m.B as "B",
                                                    m.C as "C")), 
                                            XMLELEMENT("SecondTable",
                                                       XMLFOREST(s.E as "E",
                                                                 s.F as "F")) ,
                                            xmlagg(XMLELEMENT("ThirdTable",
                                                       XMLFOREST(t.G as "G",
                                                                 t.H as "H",
                                                                 t.I as "I")))) xml_payload
            from main m, secondtable s, thirdtable t
            where m.TxnId=s.TxnId
            and   s.TxnId=t.TxnId(+)
            group by m.txnid, s.txnid, m.a, m.b, m.c, s.e, s.f;

替代方案,使用子选择并删除分组和分组加入:

            select XMLELEMENT("Event", xmlelement("Main", 
                                                XMLFOREST(m.A as "A",
                                                          m.B as "B",
                                                          m.C as "C")), 
                                                  XMLELEMENT("SecondTable",
                                                             XMLFOREST(s.E as "E",
                                                                       s.F as "F")),                                                        
                                                  (select xmlagg(XMLELEMENT("ThirdTable",
                                                             XMLFOREST(t.G as "G",
                                                                       t.H as "H",
                                                                       t.I as "I")))
                                                    from thirdtable t
                                                    where s.TxnId=t.TxnId
                                                   )) xml_payload
                  from main m, secondtable s
                  where m.TxnId=s.TxnId;

将第三个表格中的所有元素重复到一个单一表格下只需将xmlagg向下移动一个级别:

            select XMLELEMENT("Event", xmlelement("Main", 
                                                XMLFOREST(m.A as "A",
                                                          m.B as "B",
                                                          m.C as "C")), 
                                                  XMLELEMENT("SecondTable",
                                                             XMLFOREST(s.E as "E",
                                                                       s.F as "F")),                                                        
                                                  (select XMLELEMENT("ThirdTable",xmlagg(
                                                             XMLFOREST(t.G as "G",
                                                                       t.H as "H",
                                                                       t.I as "I")))
                                                    from thirdtable t
                                                    where s.TxnId=t.TxnId
                                                   )) xml_payload
                  from main m, secondtable s
                  where m.TxnId=s.TxnId;