【问题标题】:Working with XMLtable columns . Is it possible to assign collection datatypes to xmltable columns使用 XMLtable 列。是否可以将集合数据类型分配给 xmltable 列
【发布时间】:2021-09-08 12:22:34
【问题描述】:

我有一个要求,我必须将 XML 表列选择为记录数据类型,它是静态数据类型和集合的组合。我搜索了各种说 Xpath 可以返回节点列表的来源,但我怀疑我是否可以使用列的集合数据类型来存储这个节点列表。

  type MobileTable is Table of number Index by pls_integer; 

    type purchase is record (vegetables varchar2(20),fruits varchar2(30));
 
    type food is table of purchase Index by pls_integer;
     type data is record
    (Name varchar2(30), Mobile_Number MobileTable,Purchases food);
 


    <customers>
    <month>July</month>
    <day>Tuesday</day>
    <start-time>11</start-time>
     <customer>
    <Name>sally</Name>
    <Mobile-Number>999-256-00</Mobile-Number>
    <Mobile-Number>999-256-11</Mobile-Number>
    <purchase>
    <vegetables>Carrot</vegetables>
    <fruits>Apple</fruits>
    </purchase>
    <purchase>
    <vegetables>Broccli</vegetables>
    <fruits>Orange</fruits>
    </purchase>
    <customer>
    </customers>

关于 XML 只是我用来解释我的需求的一个例子,如果问题不清楚,请提出。

我的查询:

    select Name,Mobile_Number,Purchases into  data from custommers_table ct,
      xmltable('customers' 
        passing ct.cust_xml
        columns Name varchar2(20) path 'Name',
                Mobile_Number MobileTable path 'Mobile-Number',
                Purchases food path '//purchase/vegetables|//purchase/fruit')
where cust_xml_id=1;

对于 Mobile_Number 和 Purchases,我收到了无效数据类型错误。

//purchase/vegetables|//purchase/fruit

我在 W3 学校的 Xpath 语法概念下找到了这个 XPath,我不确定它的正确性,但这是我想要实现的。

请建议我是否有其他方法可以实现这一目标。

【问题讨论】:

    标签: sql oracle xpath xquery xmltable


    【解决方案1】:

    作为一种相当暴力的方法,您可以将手机号码和购买作为子 xmltype 变量获取,并循环填充集合:

    declare
      type t_mobile_numbers_tab is table of varchar2(15) index by pls_integer; 
    
      type t_purchase_rec is record (
        vegetables varchar2(20),
        fruits varchar2(30)
      );
      type t_purchases_tab is table of t_purchase_rec index by pls_integer;
    
      type t_data_rec is record (
        name varchar2(30),
        mobile_numbers t_mobile_numbers_tab,
        purchases t_purchases_tab
      );
    
      l_data t_data_rec;
      l_mobile_numbers xmltype;
      l_purchases xmltype;
    begin
      select name, mobile_numbers, purchases
      into l_data.name, l_mobile_numbers, l_purchases
      from custommers_table ct
      cross apply xmltable('customers/customer' 
        passing ct.cust_xml
        columns name varchar2(20) path 'Name',
                mobile_numbers xmltype path 'Mobile-Number',
                purchases xmltype path 'purchase/vegetables|purchase/fruits'
      )
      where cust_xml_id=1;
    
      for r in (
        select mobile_number
        from xmltable('Mobile-Number'
          passing l_mobile_numbers
          columns mobile_number varchar2(15) path '.'
        )
      )
      loop
        l_data.mobile_numbers(l_data.mobile_numbers.count) := r.mobile_number;
      end loop;
    
      for r in (
        select type, purchase
        from xmltable('*'
          passing l_purchases
          columns type varchar2(10) path 'name(.)',
                  purchase varchar2(30) path '.'
        )
      )
      loop
        if r.type = 'vegetables' then
          l_data.purchases(l_data.purchases.count).vegetables := r.purchase;
        elsif r.type = 'fruits' then
          l_data.purchases(l_data.purchases.count).fruits := r.purchase;
        end if;
      end loop;
    end;
    /
    

    第一个查询获取标量名称和两个子 xmltype 值。然后在游标查询中使用这些 xmltype 变量,并在这些游标循环中提取数字/购买并分配给子集合中的记录。

    db<>fiddle 显示中间值,并打印出集合的内容以查看填充的内容。

    使用对象类型而不是记录会更简单一些;但仍然觉得可能有更有效的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-16
      • 2018-01-02
      • 2012-08-24
      • 2017-12-06
      • 2010-10-13
      • 2012-03-08
      相关资源
      最近更新 更多