ORACLE将XML字符串解析为单独的记录

时间:2013-01-19 16:17:14

标签: sql xml oracle

我正在努力寻找几个小组的成员。组成员身份在XML中存储在ORACLE数据库中。我需要一个SQL查询来将每个成员拆分成一个单独的行。

我已经看过一些关于使用xmlsequence的帖子,但由于缺乏理解而没有成功。

示例字符串是

<D:href xmlns:D='DAV:'>/users/admin@Native Directory</D:href>
<D:href xmlns:D='DAV:'>/users/oracle@Native Directory</D:href>
<D:href xmlns:D='DAV:'>/users/user1@DomainProd</D:href>

我目前的结果是

Group       User
-------------------------------------------------------------------------
group1      <D:href xmlns:D='DAV:'>/users/admin@Native Directory</D:href>
            <D:href xmlns:D='DAV:'>/users/oracle@Native Directory</D:href>
            <D:href xmlns:D='DAV:'>/users/user1@DomainProd</D:href>
group2      <D:href xmlns:D='DAV:'>/users/admin@Native Directory</D:href>
            <D:href xmlns:D='DAV:'>/users/oracle@Native Directory</D:href>
            <D:href xmlns:D='DAV:'>/users/user1@DomainProd</D:href>
group3      <D:href xmlns:D='DAV:'>/users/admin@Native Directory</D:href>
            <D:href xmlns:D='DAV:'>/users/oracle@Native Directory</D:href>
            <D:href xmlns:D='DAV:'>/users/user1@DomainProd</D:href>

我希望我的结果设置为

Group       User
-------------------
group1      admin
group1      oracle
group1      user1
group2      admin
group2      oracle
group2      user1
group3      admin
group3      oracle
group3      user1

任何帮助将不胜感激......

由于

2 个答案:

答案 0 :(得分:1)

您可以使用XMLTABLE。由于您的XML文档似乎是行中的一个片段,我将其包装在<root>元素中。

select grp, substr(name, 
              instr(name, '/', -1) + 1,
              instr(name, '@') - instr(name, '/', -1) - 1
             ) name
  from mytab m, 
       xmltable(xmlnamespaces('DAV:' as "D"), 
                '/root/D:href' passing xmltype('<root>'||usr||'</root>')
                columns
                name varchar2(200) path './text()');

我假设一个表,其中xml列存储为名为(usr)的clob / varchar2。

group1的示例输出:

SQL> select grp, substr(name,
  2                instr(name, '/', -1) + 1,
  3                instr(name, '@') - instr(name, '/', -1) - 1
  4               ) name
  5    from mytab m,
  6         xmltable(xmlnamespaces('DAV:' as "D"),
  7                  '/root/D:href' passing xmltype('<root>'||usr||'</root>')
  8                  COLUMNS
  9                  name VARCHAR2(200) path './text()');

GRP    NAME
------ ----------
group1 admin
group1 oracle
group1 user1

http://sqlfiddle.com/#!4/435cd/1

答案 1 :(得分:0)

@DazzaL's answer是一个很好的(在大多数情况下可能更快),
但你也可以这样做:

with tt as 
(select ggroup, regexp_replace(uuser, '([[:print:]]*)(/users/)([[:alnum:]]*)(@)([[:print:]]*)','\3,') user_csv
from t)
select distinct ggroup, regexp_substr(user_csv,'[^,]+',1,level)
from tt
connect by regexp_substr(user_csv,'[^,]+',1,level) is not null
order by ggroup
我的查询中的

t是表格的名称

Here is a sqlfiddle demo