从XMLType Oracle中检索XML元素

时间:2017-08-24 15:51:32

标签: sql oracle oracle11g oracle11gr2 xmltype

有人可以帮我从Oracle中的XMLType列中检索数据吗?

drop table xml_analysis;
create table xml_analysis(id number,soft_attributes XMLType);
create table xml_softattributes(id number,soft_attributes varchar2(200));
INSERT INTO xml_analysis VALUES 
   (       1, XMLType(
              '<softattributes> 
               <attr1>ABC</attr1>
               <attr2>XYZ</attr2> 
               <attr3>PQR</attr3> 
               </softattributes>
                '));
   insert into xml_softattributes values(1,'attr1');
   insert into xml_softattributes values(1,'attr2');
   insert into xml_softattributes values(1,'attr3');
  1. 表xml_analysis包含xmltype列,其属性我不知道
  2. 表xml_softattributes包含softattributes列表(不是xpath),它们存在于xml_analysis表的xmltype列中
  3. 根据ID
  4. 加入表格

    现在我的问题是使用表xml_softattributes动态地从xml_analysis表中检索数据,我该怎么做?

    需要输出

    Softattribute Value 
    =======================  
       attr1        ABC
       attr2        XYZ
       attr3        PQR
    

    我可以想到的可能解决方案是使用动态字符串并执行,但我不想要动态字符串查询来检索数据。

2 个答案:

答案 0 :(得分:5)

您可以使用existsNodeextract功能的组合,如下所示。

SELECT b.SOFT_ATTRIBUTES,
  CASE
    WHEN existsNode (a.soft_attributes ,'/*/'
      ||b.SOFT_ATTRIBUTES) = 1
    THEN a.soft_attributes.extract('/*/'
      ||b.SOFT_ATTRIBUTES
      ||'/text()').getStringVal()
  END value
FROM xml_analysis a,
  xml_softattributes b
WHERE a.id = b.id;

*用作匹配任何子节点的通配符。例如,/ PO / * / STREET匹配作为PO元素的孙子的任何街道元素。

输出:

attr1   ABC
attr2   XYZ
attr3   PQR

答案 1 :(得分:3)

如果属性集是固定的('attr1', 'attr2', 'attr3'),那么您可以从XML结构中提取数据然后取消忽略。然后你可以用通常的方式加入另一张桌子。

select id, softattribute, value
from (
       select x.id, xt.attr1, xt.attr2, xt.attr3
       from   xml_analysis x,
              xmltable('/softattributes'
                passing x.soft_attributes
                columns
                  attr1 varchar2(100) path 'attr1',
                  attr2 varchar2(100) path 'attr2',
                  attr3 varchar2(100) path 'attr3'
              ) xt
     )
unpivot ( value 
          for softattribute in (attr1 as 'attr1', attr2 as 'attr2', attr3 as 'attr3')
        )
;

ID  SOFTATTRIBUTE  VALUE
--  -------------  -----
 1  attr1          ABC
 1  attr2          XYZ
 1  attr3          PQR

如果仅通过检查数据来了解属性集,那么UNPIVOT无法正常工作 - XMLTABLE也无法工作,因为PATH必须是一个字符串文字,在编写代码时已知(或者在动态查询编写过程中已知),它不能在运行时学习。

如果这是一个问题,您可能需要重新考虑XML结构; 'attr1'等应该是值,而不是标签,就像值一样。 (如果您打算使用EAV模型,请朝这个方向前进。)