暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 使用XMLType成员函数从重复元素中提取属性值。

ASKTOM 2021-02-02
1058

问题描述

嗨,

我正在尝试提高提取数据的一段代码的性能
从XML文档中涉及
这里是一个简化的代码,其中定义了XML文档。
通过使用EXTRACTVALUE重写选择,我已经实现了大约30% 的性能提升
使用XMLTYPE成员函数提取和GETSTRINGVAL转换为表单。
(请参阅注释的行)。
declare
 ivkX XMLType;
 nperiodsX XMLType;
 suminsX NUMBER(10);
nperiods_tab nperiods_T;
begin
ivkX:=xmltype(
'
  
   20596
   56
   156
  
 
  
  
  
 
');

-- usual
SELECT extractvalue(ivkX, '//ivk/insurance/sumins') INTO suminsX FROM DUAL;
DBMS_OUTPUT.PUT_LINE(suminsX);
-- preferred, faster, avoids context switch PLSQL <--> SQL
suminsX:=ivkX.EXTRACT('//ivk/insurance/sumins/text()').GETSTRINGVAL();
DBMS_OUTPUT.PUT_LINE(suminsX);

nperiodsX:=ivkX.EXTRACT('//ivk/nperiods');
nperiodsX.ToObject(nperiods_tab);
end;
/

ERROR at line 1:
ORA-19031: XML element or attribute nperiod does not match any in type IDB_MIG.NPERIODS_T
ORA-06512: at "SYS.XMLTYPE", line 196
ORA-06512: at line 33


我想对重复元素的属性做相同或相似的事情,比如这里的n周期元素。
但是我被一个适当的对象类型的定义卡住了。
这是我定义对象类型以提取重复值的尝试之一
元素中的datetime、datet0和days属性转换为对象表。

CREATE OR REPLACE TYPE nperiod_T AS OBJECT("@datefrom" varchar2(10),"@dateto" varchar2(10),"@days" varchar2(10));
/
CREATE OR REPLACE TYPE nperiods_T AS OBJECT("nperiod" nperiod_T);
/

我已经尝试了nperiods_T对象类型的各种其他定义,但是我一直得到
ORA-19031错误或类型不一致。
你能告诉我我应该如何构造对象类型来做到这一点吗?
我使用的数据库是Oracle 12.1.0.2。

谢谢,
帕维尔

专家解答

我不知道该如何做您想要的事情。我尝试了各种各样的事情,但没有运气。

也就是说,一些可能有帮助的指针:

该对象将具有n周期项的数组,因此您需要声明嵌套表类型。当前对象仅允许n周期下的一个n周期元素。

您可以通过n周期元素循环,将每个元素分配给一个对象,你去:

create or replace type "nperiod" force as object(
  "@datefrom" varchar2(10),"@dateto" varchar2(10),"@days" varchar2(10)
); 
/

declare 
 ivkX XMLType; 
 nperiodsX XMLType; 
 x xmltype;
 n number;
 p "nperiod";
begin 
ivkX:=xmltype( 
' 
   
   20596 
   56 
   156 
   
  
   
   
   
  
'); 
  
  nperiodsX:=ivkX.EXTRACT('//ivk/nperiods'); 

  select xmlcast ( 
    xmlquery ( 
      'count(//nperiods/*)' passing nperiodsX returning content 
    ) as number 
  ) 
  into   n 
  from   dual;

  for i in 1 .. n loop
    x := nperiodsX.EXTRACT('//nperiod['||i||']'); 
    x.toObject ( p );
    dbms_output.put_line ( p."@datefrom" );
  end loop;
end; 
/

1965-10-03
2005-09-01
2013-01-01


XMLCast...XMLQuery select是获取n周期下的元素数量; 在PL/SQL中可能有一种方法可以做到这一点,但是我现在找不到它!

也可能值得研究XMLTable。这将使用SQL将XML转换为关系行和列。这将有一个上下文切换,但它可以使您减少提取调用的次数,从而赢得一个很好的胜利:

select * from xmltable (
  'ivk/nperiods/nperiod'
  passing xmltype ( '
  
   20596
   56
   156
  
 
  
  
  
 
' )
  columns 
    datefrom varchar2(10) path '@datefrom',
    dateto varchar2(10) path '@dateto',
    days integer path '@days'
);

DATEFROM      DATETO         DAYS   
1965-10-03    1965-10-03          1 
2005-09-01    2009-12-31       1583 
2013-01-01    2013-12-31          8 

文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论