2017-02-10 75 views
1

我的XML看起來是這樣的:怎麼辦遍歷在PL/SQL 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> 

我想輸出:

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 

如何循環在XML和插入數據到Oracle表最低性能問題,假設1000條記錄?

+0

爲什麼選擇PL/SQL?爲什麼不是普通的SQL? –

+0

你可以發佈你已經編碼並描述什麼是錯的? – laylarenee

+0

@AlexPoole和OP,爲什麼SQL?任何通用語言(Java,C#,PHP,Python,VB)都可以解析XML文檔並調用其他專用代碼,如XPath和XSLT。儘管我們喜歡它,但在一天結束時,SQL是一種特殊用途的語言。關閉找到試圖發送電子郵件與存儲過程(喘氣)(嘆氣)的海報! – Parfait

回答

3

您可以使用多個XMLTable級別來執行此操作。一個XMLTable獲取等級,組,命名等,並將當前行作爲XMLType對象。第二個XMLTable然後從提取的行中提取所有員工名稱。

的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; 

它得到:

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 

您可以插入查詢的結果到另一個表insert into some_table (column1, column2, ...) select ...

一般而言,如果值來自表格,則不需要PL/SQL來實現此目的。

如果您的XML在PL/SQL變量中,例如從您的Web服務調用中,您可以使用該變量執行相同的操作,而不是直接從表中選擇。你仍然可以直接插入你的目標表。在這個例子中,我假設你的本地PL/SQL變量與Web服務結果被稱爲l_xml,並且是XMLType類型;併發明瞭表和列名,所以你會明顯地使用自己的以假亂真:

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; 

如果你正在檢索Web服務結果爲CLOB,你可以將其轉換爲呼叫的一部分:

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

您不需要使用任何循環。你可能在同一個查詢上使用一個遊標循環,並將每個結果逐一插入到你的表中,但是這隻會減慢它的好處。

+0

感謝您的幫助,但案件是如何循環在那xml和插入數據到最低性能問題的oracle表中,假設1000條記錄? – user2728057

+0

@ user2728057 - 您可以簡單地將該查詢的結果插入表中。爲什麼要使用循環,這比簡單的'insert ... select'效率低?1000個XML記錄來自哪裏,另一個表,一個文件....? –

+0

我從我的存儲過程調用Web服務並獲取XML響應。我想解析XML並將值插入到oracle表中。 – user2728057