2012-10-19 61 views
17

如何將嵌套的xml文件加載到數據庫表中?oracle plsql:如何解析XML並插入表

<?xml version="1.0" ?> 
<person> 
    <row> 
     <name>Tom</name> 
     <Address> 
      <State>California</State> 
      <City>Los angeles</City> 
     </Address> 
    </row> 
    <row> 
     <name>Jim</name> 
     <Address> 
      <State>California</State> 
      <City>Los angeles</City> 
     </Address> 
    </row> 
</person>  

在這個xml中,person是表名,name是字段名,Tom是它的字段值。 地址是一個子表和州和城市是兩列內的地址。我想將人行插入到人員表中,如果失敗,請不要插入到地址表中。這個XML可能非常大。什麼是最好的解決方案來做到這一點?

+0

試試這個https://forums.oracle.com/forums/thread.jspa?messageID=10269899 – user75ponic

+0

我有一點不同的XML樹,請幫助:) http://stackoverflow.com/questions/18583872/oracle-xml-skip-not-exist-node – zrosystem

回答

23

您可以加載XML文檔到XMLType,然後對其進行查詢,例如:

DECLARE 
    x XMLType := XMLType(
    '<?xml version="1.0" ?> 
<person> 
    <row> 
     <name>Tom</name> 
     <Address> 
      <State>California</State> 
      <City>Los angeles</City> 
     </Address> 
    </row> 
    <row> 
     <name>Jim</name> 
     <Address> 
      <State>California</State> 
      <City>Los angeles</City> 
     </Address> 
    </row> 
</person>'); 
BEGIN 
    FOR r IN (
    SELECT ExtractValue(Value(p),'/row/name/text()') as name 
      ,ExtractValue(Value(p),'/row/Address/State/text()') as state 
      ,ExtractValue(Value(p),'/row/Address/City/text()') as city 
    FROM TABLE(XMLSequence(Extract(x,'/person/row'))) p 
    ) LOOP 
    -- do whatever you want with r.name, r.state, r.city 
    END LOOP; 
END; 
+0

這可能會有所幫助,但一個大問題是,我可能不知道標記名稱,輸入是動態XML所有不同的表名和文件 – Frank

+3

那麼,你需要知道標籤是什麼,否則代碼應該怎麼知道在哪裏插入數據? –

+0

我已通過使用dbms_xmldom API解決了此問題。感謝您的幫助 – Frank

6
CREATE OR REPLACE PROCEDURE ADDEMP 
    (xml IN CLOB) 
AS 
BEGIN 
    INSERT INTO EMPLOYEE (EMPID,EMPNAME,EMPDETAIL,CREATEDBY,CREATED) 
    SELECT 
     ExtractValue(column_value,'/ROOT/EMPID') AS EMPID 
     ,ExtractValue(column_value,'/ROOT/EMPNAME') AS EMPNAME 
     ,ExtractValue(column_value,'/ROOT/EMPDETAIL') AS EMPDETAIL 
     ,ExtractValue(column_value,'/ROOT/CREATEDBY') AS CREATEDBY 
     ,ExtractValue(column_value,'/ROOT/CREATEDDATE') AS CREATEDDATE 
    FROM TABLE(XMLSequence(XMLType(xml))) XMLDUMMAY; 

    COMMIT; 
END; 
8
select * 
FROM XMLTABLE('/person/row' 
     PASSING 
      xmltype(' 
       <person> 
        <row> 
         <name>Tom</name> 
         <Address> 
          <State>California</State> 
          <City>Los angeles</City> 
         </Address> 
        </row> 
        <row> 
         <name>Jim</name> 
         <Address> 
          <State>California</State> 
          <City>Los angeles</City> 
         </Address> 
        </row> 
       </person> 
      ') 
     COLUMNS 
      --describe columns and path to them: 
      name varchar2(20) PATH './name', 
      state varchar2(20) PATH './Address/State', 
      city varchar2(20) PATH './Address/City' 
    ) xmlt 
; 
+0

當我在內有多個地址標記時,它就會失敗。我應該修改什麼來循環使用同名多個標籤?請幫助 – Murali

+0

如果您想訪問第一個,那麼xpath將如下所示:'./Address[1]/City' – daggett

2

您將需要編寫大量的代碼來處理與Oracle複雜的XML文件。如果你有大量的XML,那麼性能可能也是一個問題。企業級XML解析器可讓您將大量複雜的XML文件處理爲關係格式,無需編寫任何代碼。本博客文章介紹如何bulk load complex XML files to Oracle無需編寫任何代碼