1

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

输入

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列要么是空的,要么是带有根元素的 XML 文档<t>。下<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

4

1 回答 1

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
于 2013-07-24T03:28:48.653 回答