sql查询中的父xml,xpath

时间:2016-10-24 13:01:29

标签: xml oracle xpath

我有这样的xml:

< person code="SNIPER">

    <type code="SINGLE" />

<version code="1" dateFrom="2015-03-20" />
</version>

<version code="2" dateFrom="2012-06-15" />
</version>

 < /person>

我有SQL查询:

select extract(VALUE(cd_xml), 'version/@code').getstringval() code
       ,cast(to_timestamp_tz(replace(extract(VALUE(cd_xml), 'version/@dateFrom')
                                                   .getstringval(), 'T', ''),
                                           'yyyy-mm-dd') as date) datefrom

from table(xmlsequence(extract(get_xml, '/*/person/version'))) cd_xml

它返回两行:

1  2015-03-10

2  2012-06-15

我想获得这样的行:

single 1  2015-03-10

single 2  2012-06-15

sniper 1  2015-03-10

sniper 2  2012-06-15

怎么做? 我尝试了与父条款不同的thigs,但我没有做到:(

1 个答案:

答案 0 :(得分:0)

The extract function is deprecated;您可以使用它,但最好使用XMLQuery/XMLTable,例如假设get_xml是一个函数,它将正确格式化的XML作为XMLType返回:

select *
from xmltable('/persons/person/version'
  passing get_xml
  columns person_code varchar2(10) path './../@code',
    type_code varchar2(10) path './../type/@code',
    version_code number path '@code',
    version_datefrom date path '@dateFrom'
);

使用静态XML进行演示,根据您发布的内容进行修改以匹配您使用的模式:

select *
from xmltable('/persons/person/version'
  passing xmltype('<persons>
  <person code="SNIPER">
    <type code="SINGLE" />
    <version code="1" dateFrom="2015-03-20" />
    <version code="2" dateFrom="2012-06-15" />
  </person>
</persons>')
  columns person_code varchar2(10) path './../@code',
    type_code varchar2(10) path './../type/@code',
    version_code number path '@code',
    version_datefrom date path '@dateFrom'
);

PERSON_COD TYPE_CODE  VERSION_CODE VERSION_DA
---------- ---------- ------------ ----------
SNIPER     SINGLE                1 2015-03-20
SNIPER     SINGLE                2 2012-06-15

您的操作建议dateFrom实际上是一个完整的时间戳,更像是'2015-03-20T12:34:56+04:00';如果您只想要日期部分,那么您也可以更简单地获取它,将列提取为timestamp with time zone然后在最后进行投射:

select person_code, type_code, version_code,
  cast(version_datefrom as date) as version_datefrom
from xmltable('/persons/person/version'
  passing xmltype('<persons>
  <person code="SNIPER">
    <type code="SINGLE" />
    <version code="1" dateFrom="2015-03-20T12:34:56+04:00" />
    <version code="2" dateFrom="2012-06-15T23:00:00+00:00" />
  </person>
</persons>')
  columns person_code varchar2(10) path './../@code',
    type_code varchar2(10) path './../type/@code',
    version_code number path '@code',
    version_datefrom timestamp with time zone path '@dateFrom'
);