简体   繁体   English

如何在PL / SQL中通过XML进行循环

[英]How to do loops through XML in PL/SQL

My XML looks like this : 我的XML看起来像这样:

<root>
  <row>
    <grade>A</grade>
    <Employee>
      <Name>ROBERT SUKIMIN</Name>
      <company>ABC</company>     
    </Employee>
    <Group>117761020</Group>
    <Designation>2014-03-21</Designation>
    <Company_code>5813044</Company_code>
  </row>
  <row>
    <grade>B</grade>
    <Employee>
      <Name>CECIL PAINEM</Name>
      <company>XYZ</company>
    </Employee>
    <Employee>
      <Name>SUGRIWO</Name>
      <company>BCA</company>
    </Employee>
    <Group>40560050</Group>
    <Designation>2012-05-03</Designation>
    <Company_code>0</Company_code>
  </row>
</root>

I would like output: 我想要输出:

A Robert Sukimin ABC 117761020 2014-03-21 5813044
B CECIL PAINEM XYZ 405600 2012-05-03 0
B SUGRIWO BCA 405600 2012-05-03 0

How loop in that xml and insert data into oracle table with minimal performance issue, assuming the 1000 record? 假设1000记录,如何在该xml中循环并将数据插入到具有最小性能问题的oracle表中?

You can use multiple XMLTable levels to do this. 您可以使用多个XMLTable级别来执行此操作。 One XMLTable gets the grade, group, designation etc. and also the current row as XMLType object. 一个XMLTable获取成绩,组,名称等,并将当前行作为XMLType对象。 The second XMLTable then extracts all of the employee names from that extracted row. 然后,第二个XMLTable从提取的行中提取所有员工姓名。

With a CTE just to generate your base XML: 使用CTE生成基本XML:

with t (xml) as (
  select xmltype('<root>
  <row>
    <grade>A</grade>
    <Employee>
      <Name>ROBERT SUKIMIN</Name>
      <company>ABC</company>     
    </Employee>
    <Group>117761020</Group>
    <Designation>2014-03-21</Designation>
    <Company_code>5813044</Company_code>
  </row>
  <row>
    <grade>B</grade>
    <Employee>
      <Name>CECIL PAINEM</Name>
      <company>XYZ</company>
    </Employee>
    <Employee>
      <Name>SUGRIWO</Name>
      <company>BCA</company>
    </Employee>
    <Group>40560050</Group>
    <Designation>2012-05-03</Designation>
    <Company_code>0</Company_code>
  </row>
</root>') from dual
)
select x.grade, y.name, y.company, x.group_num, x.designation, x.company_code
from t
cross join xmltable ('/root/row'
  passing t.xml
  columns grade varchar2(1) path 'grade',
    row_xml xmltype path '.',
    group_num number path 'Group',
    designation varchar2(10) path 'Designation',
    company_code number path 'Company_code'
) x
cross join xmltable ('/row/Employee'
  passing x.row_xml
  columns name varchar2(30) path 'Name',
    company varchar2(5) path 'company'
) y;

which gets: 获得:

G NAME                           COMPA  GROUP_NUM DESIGNATIO COMPANY_CODE
- ------------------------------ ----- ---------- ---------- ------------
A ROBERT SUKIMIN                 ABC    117761020 2014-03-21      5813044
B CECIL PAINEM                   XYZ     40560050 2012-05-03            0
B SUGRIWO                        BCA     40560050 2012-05-03            0

You can insert the result of that query into another table with insert into some_table (column1, column2, ...) select ... . 您可以将该查询的结果插入到另一个表中,并insert into some_table (column1, column2, ...) select ...

In general you don't need PL/SQL to achieve this if the value is coming from a table. 通常,如果值来自表,则不需要PL / SQL来实现此目的。

If you have your XML in a PL/SQL variable, eg from your web service call, you can do the same thing using that variable instead of selecting directly from a table. 如果您在PL / SQL变量中使用XML,例如从Web服务调用,您可以使用该变量执行相同的操作,而不是直接从表中选择。 You can still insert directly into your target table. 您仍然可以直接插入目标表。 In this example I've assumed your local PL/SQL variable with the web service result is called l_xml and is of type XMLType; 在这个例子中,我假设你的本地PL / SQL变量带有web服务结果,名为l_xml ,类型为XMLType; and invented the table and column names so you'd obviously use your own real ones: 并发明了表格和列名称,因此您显然可以使用自己的真实名称:

declare
  l_xml XMLType;
  ...
begin
  -- call web service to populate l_xml
  ...

  insert into you_table(grade, name, company, group_num, designation, company_code)
  select x.grade, y.name, y.company, x.group_num, x.designation, x.company_code
  from xmltable ('/root/row'
    passing l_xml    -- your local XMLType variable
    columns grade varchar2(1) path 'grade',
      row_xml xmltype path '.',
      group_num number path 'Group',
      designation varchar2(10) path 'Designation',
      company_code number path 'Company_code'
  ) x
  cross join xmltable ('/row/Employee'
    passing x.row_xml
    columns name varchar2(30) path 'Name',
      company varchar2(5) path 'company'
  ) y;

  ...
end;

If you're retrieving the web service result into a CLOB you can convert it as part of the call: 如果您要将Web服务结果检索到CLOB中,则可以将其作为调用的一部分进行转换:

  ...
  from xmltable ('/root/row'
    passing XMLType(l_clob)    -- your local CLOB variable
  ...

You don't need to use any loops. 您不需要使用任何循环。 You could use a cursor loop over that same query and insert each result into your table one by one, but that would just slow it down for no benefit. 可以在同一个查询上使用游标循环,并将每个结果逐个插入到您的表中,但这样做只会减慢速度而不会带来任何好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM