如何从Oracle中的XMLType获取数据集

时间:2013-07-24 00:44:47

标签: sql xml oracle

如何从存储在行中的一组xml文档中提取数据集作为SQL select语句?这是一个说明问题的示例任务。

输入

create table circle
  ( id       number         not null primary key
  , name_xml varchar2(2000) 
  )
/

insert into circle
 select 1, '<t><person><firstn>Sean       </firstn> <lastn>Durkin     </lastn></person>' ||
              '<person><firstn>Tom        </firstn> <lastn>Sawyr      </lastn></person></t>' from dual union all
 select 2, '<t><person><firstn>Philip     </firstn> <lastn>Marlowe    </lastn></person>' ||
              '<person><firstn>John       </firstn> <lastn>Wayne      </lastn></person>' ||
              '<person><firstn>Constantine</firstn> <lastn>Palaeologus</lastn></person></t>' from dual union all
 select 3, null from dual;

因此,在表圈中,我们有5个人分布在3个表行中。每个人都用名字(firstn)和姓氏(lastn)标识。

输入结构

name_xml列为空或具有根元素<t>的XML文档。 <t>下的<person>是任意数量的<person><firstn>下的<lastn>People ----------------------- Sean Durkin Tom Sawyr Philip Marlowe John Wayne Constantine Palaeologus 按此顺序排列。列表中显示的空格仅用于提高可读性,而不是真实数据。

预期输出

我们希望获得全名列表。它应该是单个字符串列。从上面的数据我们预计输出...

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi

环境

我的数据库引擎是select extract( name_parts, '/person/firstn') || ' ' || extract( name_parts, '/person/firstl') as People from ( select extract( XMLType( name_xml), '/t/person').getStringVal() as name_parts from circle where name_xml is not null)

到目前为止我尝试了什么

根据我的阅读和理解,这个查询应该有用......

inconsistent data type

但这会返回错误{{1}}。

1 个答案:

答案 0 :(得分:3)

11:28:27 SYSTEM@dwal> l
  1  select
  2   trim(extractvalue( value(t), '/person/firstn')) ||' '||
  3   trim(extractvalue( value(t), '/person/lastn')) as people
  4  from circle
  5  ,table(xmlsequence(extract(xmltype(name_xml), '/t/person'))) t
  6* where name_xml is not null
11:28:28 SYSTEM@dwal> /

PEOPLE
----------------------------------------
Sean Durkin
Tom Sawyr
Philip Marlowe
John Wayne
Constantine Palaeologus

Elapsed: 00:00:00.01

甚至使用XMLTable更简单

11:36:47 SYSTEM> l
  1  select
  2    t.fname, t.lname
  3   from circle
  4   ,xmltable('/t/person'
  5    passing xmltype(circle.name_xml)
  6    columns
  7     fname varchar2(20) path '/person/firstn',
  8     lname varchar2(20) path '/person/lastn'
  9  ) t
 10*  where name_xml is not null
11:36:56 SYSTEM> /

FNAME                LNAME
-------------------- --------------------
Sean                 Durkin
Tom                  Sawyr
Philip               Marlowe
John                 Wayne
Constantine          Palaeologus

Elapsed: 00:00:00.12
11:36:58 SYSTEM> @ver

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE    10.2.0.3.0      Production
TNS for Solaris: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production

Elapsed: 00:00:00.01