技術分享:Oracle PLSQL讀取(解析)Excel文檔

Introduction介紹

Excel文檔的數據如何讀取到Oracle數據庫一直是值得深究的問題。

目前相信大部分程序員都是直接用工具將Excel的數據讀取到Oracle數據庫的。例如ToadPL/SQL DeveloperExcel數據導入功能。

也有一部分程序開發的是:先將Excel轉換爲一個逗號分隔符等的文本文件(CSV),然後寫代碼通過特定的符號(TAB符號或者逗號等)將數據拆分並且識別。

其實上面的讀取Excel的辦法都不是最好用的辦法。舉個例子,用Toad等工具來做,程序開發工程師來做是可以的,但是不可以將這個工作交給普通用戶做(當用戶想導入數據的時候)。如果用文本來做,先要做一個轉換,對於用戶來說無疑是多做了一個動作,操作不方便。


綜上所述,其實最方便的還是:如何在Oracle數據庫用PL/SQL直接讀取Excel的內容,這纔是最好的做法。

PL/SQL直接解析並讀取Excel,有一個蠻不錯的辦法,就是用JavaPOI組件。確實是不錯,但是要先導入POIJava類,然後再在Oracle裏面寫一段Pkgclass類解析Excel。是可行的。我也研究過,發現有一些限制(可能是和POI的版本太低有關係)

這裏提出一個更加好的辦法,就是用Oracle自帶的utl_raw 包(二進制處理包)和dbms_xmldom包,將Excel文件對應的Blob大文本字段進行解析,最後再將解析出來的內容用管道表函數輸出一個虛擬的表格。這樣子就是很直觀了,直接將一個Excel文檔解析爲一個表格!

可能大家比較關心解析的效率。所以針對效率方面,經過測試,還是非常不錯的。下面有專門測試解析效率的主題。

另外一個比較關心的問題:Excel裏面可以有很多公式列,那對於公式列讀取出來的結果是什麼?另外,一些特殊的格式欄位是否可以正確識別?經過測試,這些都可以得到正確的解析。例如公式列,解析的是公式計算的結果。


先簡單測試一下實現的效果。

現在有這麼一個Excel文檔:XLS文件導入樣本.xls,想將它導入到Oracle數據庫中。


然後將它上傳到服務器的某個文件夾。注意,這個文件路徑(/data/uat/apps/apps_st/appl/attchment/12.0.0/BATCH_UPLOAD_TEMP/)必須是在all_directories有定義的。否則用PLSQL無法直接讀取文件。值得一提的是,這個步驟並不是必須的,你也可以將Excel文件上傳到Blob大字段中,然後再直接讀取。常見的是FND_LOBS表的FILE_DATA字段。



最後一步,用下面的函數就可以直接讀取出Excel文本的內容了(注意輸入的參數)

SELECT* FROM TABLE(XYG_PUB_DATA_UPLOAD_PKG.CONVER_EXCEL_TO_TAB(XYG_ALD_FILE_PKG.CONVERT_FILE_BLOB('XYG_BATFILE','XLS文件導入樣本.xls'),'',1))

必須要說明的是,欄位BATCH_CODE=工作表的名稱。

如果有多個工作表,那BATCH_CODE是不同的。


附上Blob字段的Excel的讀取方法:

SELECT * FROM TABLE(XYG_PUB_DATA_UPLOAD_PKG.CONVER_EXCEL_TO_TAB((SELECT FILE_DATA FROM FND_LOBS WHERE FILE_ID = 81171130),NULL,1));


注意和說明

如果是用Excel直接導入,需要注意的地方:

目前只支持30個欄位導入!應該是足夠了!另外,管道表函數的對象的每個欄位都是Varchar2類型,內容最長4000字節。

由於一個Excel可能會有多個工作表,所以,在導入的時候,必須要指定導入的Excel的工作表頁籤的名稱。

完全支持直接日期欄位的導入!日期欄位的格式也沒限制。非常好!

對於數字的類型,由於系統自動轉換爲浮點型,爲了轉換的時候不出異常,所以精度不可以超過15位。

對於公式列,它也完美支持!導入的結果就是公式的計算結果。舉個例子,一個欄位引用另外一個日期的欄位的,那導入的就是日期!

如果用戶在打開Excel(未關閉文檔的情況下),也可以用FND的標準加載功能直接加載。不過必須要注意導入之前先保存。

目前已經完美支持xlsxlsx文檔的導入,系統會自動對導入的文檔進行識別,然後分別調用不同的代碼,將文檔的內容解析出來。

  但是,我覺得用xls是最好的,因爲並不是所有的電腦都安裝了2003以上的版本,用xls是最大兼容性的。

導入效率的測試

效率測試:

解析文檔:DG訂單排產順序20150423.xls

文檔大小:1.5mb,數據量:4600行。欄位數:27,其中有某些字段的內容比較多,例如物料編碼描述等

解析時間:36秒。

解析文檔:科目爲差旅費.xls

文檔大小:3mb,數據量:9000行。欄位數:20,其中有某些字段的內容比較多,例如2個科目的描述字段等

解析時間:65

解析文檔:20150212用戶職責明細導出.xls

文檔大小:577kb,數據量:3000行,欄位數:11。字段內容比較少。

解析時間:14

解析文檔:數據收集模板(深圳汽玻夾層第二批)匡國平2011-11-08.xls

文檔大小:347kb,數據量:1572行,欄位數:17。字段的內容都不多。以數字爲主。

解析時間:7

從上面發現一個規律,基本上解析時間和文檔的大小成正比。

平均1mb的文件的解析時間要30秒左右。

應該還是可以接受的,因爲導入的數據量一般不會很多!


需要注意的是,這個數據量不單純是指記錄行數,也包括記錄的內容的多少。例如有某些字段的內容如果很多的話,就算行數少,數據量也很大!


完整文檔:http://wenku.baidu.com/view/bff55ea35901020207409cb2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章