上周遇到xml文件導入到oracle數據庫中,發現正常的xml轉成excle格式導入,只針對於1m以下的xml文件。當xml文件太大的時候,就沒有作用了。
這時候,我找到了兩種辦法,一個是java,一個是數據庫的存儲過程,但是數據庫的存儲過程還有些問題,需要自己琢磨一會。
現在就展示java的用法將xml文件導入到oracle數據庫中:
首先需要三個jar包:
dom4j-1.6.1.jar(因為采用dom4j輔助存入,所以這個是必要的)
jaxen-1.1.1.jar(使用dom4j解析XML時,要快速獲取某個節點的數據,使用XPath是個不錯的方法)
ojdbc6.jar(和數據庫打交道)
jar包可以直接在maven官網中下載,方便快捷。
導入到數據庫的xml文件的格式為:
一:DbUtil類:
package com.wj; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class DbUtil { /** * @throws SQLException * @Title: getConnection * @Description: 取得Connection * @param @return * @return Connection * @throws */ public static Connection getConnection() { // 加載驅動,使用反射來實現 Connection conn = null; try { //驅動連接 Class.forName("oracle.jdbc.driver.OracleDriver"); // 連接 String url = "jdbc:oracle:thin:@10.10.54.44:15211:credit"; String username = "creditxf"; //連接數據庫的用戶名 String password = "credit"; //連接數據庫的密碼 conn = DriverManager.getConnection(url, username, password); //進行連接 } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return conn; } public static void close(PreparedStatement pstmt, Connection conn) { try{ if(conn !=null){ conn.close(); } }catch(Exception e){ }finally{ try{ if(pstmt!=null){ pstmt.close(); } }catch(Exception e){ e.printStackTrace(); } } } }
二:TestXMLImport
package com.wj; import java.io.File; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class TestXMLImport { public static void main(String[] args) throws SQLException { // TODO Auto-generated method stub // 執行插入的SQL語句, String sql="insert into TB_SWZJ_AJNSRMD(NSRSBH, XH, NSRMC, PJND) values (?, ?, ?, ?)"; Connection conn = null; PreparedStatement pstmt = null; try { conn = DbUtil.getConnection(); pstmt = conn.prepareStatement(sql); // 讀取xml文件存放的路徑 Document doc=new SAXReader().read(new File("D:\\JAVADEMO\\XML\\xml\\TB_SWZJ_AJNSRMD_00001.xml")); // 查找對應的信息,從XMl中找對應的層層關系,我的xml文件中,一開始只是Rows,然后每條數據為Row。 List itemList= doc.selectNodes("/Rows/Row"); // 遍歷 for(Iterator iter=itemList.iterator();iter.hasNext();){ Element el=(Element) iter.next(); // 使用Element的elementText屬性取值,將值一一取出來,這個沒有取xml文件中TRANS_DM_TONG_INSERTDATE字段,是因為我需要
系統時間作為時間字段,默認時間為sysdate
String NSRSBH=el.elementText("NSRSBH"); String XH=el.elementText("XH"); String NSRMC=el.elementText("NSRMC"); String PJND=el.elementText("PJND"); // 通過pstmt賦值 pstmt.setString(1, NSRSBH); pstmt.setString(2, XH); pstmt.setString(3,NSRMC); pstmt.setString(4, PJND); pstmt.addBatch(); } pstmt.executeBatch(); // 提示 System.out.println("將XML導入數據庫成功"); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ // 關閉 DbUtil.close(pstmt,conn); } } }
這樣就可以將數據導入到數據庫里面了,親測有效。
下面放出我困惑很久的存儲過程(親測無效,但是我依舊不知道怎么辦的) 執行無結果,運行不報錯:
CREATE OR REPLACE PROCEDURE addRow(file_path VARCHAR2,log_path VARCHAR2) AS --//XML解析器 xmlPar XMLPARSER.parser := XMLPARSER.NEWPARSER; --//DOM文檔對象 doc xmldom.DOMDocument; len integer; RowNodes xmldom.DOMNodeList; chilNodes xmldom.DOMNodeList; tempNode xmldom.DOMNode; tempArrMap xmldom.DOMNamedNodeMap; --================================ --以下變量用於獲取XML節點的值 XH varchar2(20); NSRSBH varchar2(200); NSRMC varchar2(500); PJND varchar2(200); TRANS_DM_TONG_INSERTDATE TIMESTAMP(6); tmp integer; --================================ BEGIN xmlPar := xmlparser.newParser; xmlparser.setErrorLog( xmlPar, log_path); xmlparser.parse(xmlPar, file_path); doc := xmlparser.getDocument( xmlPar ); -- 釋放解析器實例 xmlparser.freeParser(xmlPar); -- 獲取所有Row元素 RowNodes := xmldom.getElementsByTagName( doc, 'Row' ); len := xmldom.getLength( RowNodes ); --遍歷所有Row元素 FOR i in 0..len-1 LOOP --獲取第i個Row tempNode := xmldom.item( RowNodes, i ); --所有屬性 tempArrMap := xmldom.getAttributes(tempNode); --獲取所有子節點 chilNodes := xmldom.getChildNodes(tempNode); --獲取子節點的個數 tmp := xmldom.GETLENGTH( chilNodes ); --獲取各個子節點的值 NSRSBH := xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item( chilNodes, 0 ))); XH := xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item( chilNodes, 1 ))); NSRMC := xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item( chilNodes, 2 ))); PJND := xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item( chilNodes, 3 ))); TRANS_DM_TONG_INSERTDATE := xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item( chilNodes, 4 ))); --插入數據 INSERT INTO TB_SWZJ_AJNSRMD VALUES (NSRSBH,XH,NSRMC,PJND,TRANS_DM_TONG_INSERTDATE); COMMIT; END LOOP; -- 釋放文檔對象 xmldom.freeDocument(doc); EXCEPTION WHEN OTHERS THEN DBMS_output.PUT_LINE(SQLERRM); END addRow;
運行: call addRow('D:/DEMO/ANS.xml','D:/DEMO/xmllog.txt');
有大哥幫小弟解決 這個問題的,小弟感激不盡。