【问题标题】:Retrieving XML elements from XMLType Oracle从 XMLType Oracle 检索 XML 元素
【发布时间】:2017-08-24 15:51:31
【问题描述】:

有人可以帮我从 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 包含软属性列表(不是 xpath),它们存在于 xml_analysis 表的 xmltype 列中
  3. 表根据 id 连接

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

需要输出

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

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

【问题讨论】:

  • 属性名称是一成不变的(只能是'attr1''attr2''attr3'),还是需要允许它们任意,并根据xml_softattributes?如果是前者,可以用静态代码来完成。否则,您将需要动态代码(很可能),但有人会问为什么您没有更通用的 XML 结构,其中 'attr1''ABC''attr2''XYZ' 等是相同类型节点的两个“值”。无论哪种方式,这看起来都像是某种 EAV 模型……应该先修复它吗?
  • @mathguy:不,属性名称没有模式,它可以是任何东西,基于 xml_softattributes 表值。要求是,我们有一组特定 csv 的软属性,例如在我们的例子中为 1,我们不想在表中创建列,因此查看此 xml_softattributes 表并在 xml_analysis 表中基于该表动态创建 xml。稍后我们需要检索此属性以进行某些报告。但结构将是attribute_name 和 value。我们还可以存储 xml 数据,例如'attr1ABC'
  • @GauravSoni - 您评论中的最后一句话正是我的建议/建议:如果您的 XML 数据以这种方式构建,您可以使用 XMLTABLE 函数从XMLTYPE 事先不知道所有可能属性的名称;并且您不需要 UNPIVOT,数据已经以所需的列格式提取。

标签: sql oracle oracle11g oracle11gr2 xmltype


【解决方案1】:

您可以使用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

【讨论】:

    【解决方案2】:

    如果属性集是固定的 ('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 模型中工作,请一直朝那个方向前进。)

    【讨论】:

      猜你喜欢
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 2014-07-23
      • 2013-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多