如何在Oracle上使用SQL查询生成XML

时间:2016-05-19 01:12:55

标签: sql xml oracle xslt

我在Oracle上有一个非规范化的数据库表,其中包含以下示例数据:

 repdate | house | house_type | house_addr | person_name | gender | rent_amt
---------|-------|------------|------------|-------------|--------|----------
01/03/16 | hs01  | 4-bed      | 1 pine st  | Bruce       | M      | 500
01/03/16 | hs01  | 4-bed      | 1 pine st  | Alfred      | M      | 300
01/03/16 | hs01  | 4-bed      | 1 pine st  | Selina      | F      | 400
01/03/16 | hs03  | 1-bed      | 4 baker rd | Joan        | F      | 200
01/03/16 | hs02  | 3-bed      | 7 pod st   | Barry       | M      | 400
01/03/16 | hs02  | 3-bed      | 7 pod st   | Caitlin     | F      | 400

我想从这个表中生成一个标准化的XML,理想情况下如下:

<?xml version="1.0" encoding="UTF-8"?>
<records repdate="01/03/16">
  <record house="hs01" house_type="4-bed" house_addr="1 pine st">
    <lineitems>
      <lineitem person_name="Bruce" gender="M" rent_amt="500" />
      <lineitem person_name="Alfred" gender="M" rent_amt="300" />
      <lineitem person_name="Selina" gender="F" rent_amt="400" />
    </lineitems>
  </record>
  <record house="hs02" house_type="3-bed" house_addr="7 pod st">
    <lineitems>
      <lineitem person_name="Barry" gender="M" rent_amt="400" />
      <lineitem person_name="Caitlin" gender="F" rent_amt="400" />
    </lineitems>
  </record>
  <record house="hs03" house_type="1-bed" house_addr="4 baker rd">
    <lineitems>
      <lineitem person_name="Joan" gender="F" rent_amt="200" />
    </lineitems>
  </record>
</records>

我正在尝试XMLElement和XMLAgg函数,但有点卡住了。 我还做了一些研究,我可以为此生成一个简单的XML,并使用XSLT转换来应用样式表来获得我需要的结果。

哪种方法更好,哪种方法最简单?

感谢任何能够帮助解决这个问题的人。感谢。

1 个答案:

答案 0 :(得分:1)

我认为这是实现它的最简单方法。将为不同的日期生成分离的xml。

  select xmlelement("records", XMLATTRIBUTES(repdate as "repdate"), xmlagg(rec order by repdate, house))
    from (  select xmlelement(
                     "record"
                   , XMLATTRIBUTES(house as "house", house_type as "house_type", house_addr as "house_addr")
                   , xmlelement(
                       "lineitems"
                     , xmlagg(
                         xmlelement(
                           "lineitem"
                         , XMLATTRIBUTES(person_name as "person_name", gender as "gender", rent_amt as "rent_amt")))))
                     rec
                 , repdate
                 , house
              from your_table
          group by house
                 , house_type
                 , house_addr
                 , repdate)
group by repdate