一個ORACLE匯入和匯出XML檔案的例子

lishiran發表於2007-06-06
詳細請檢視......[@more@]

匯入:
/*****************************************************************************
過程名稱:add_to_stockmarket
引數1:fileName in varchar2 接收使用者輸入的xml檔名
功能:將xml檔案中的資料匯入到Stockmarket資料表中
*****************************************************************************/
create or replace procedure add_to_stockmarket(fileName IN varchar2) as
document xmldom.DOMDocument;--宣告文件物件模型
subelement xmldom.DOMElement;--宣告元素型別
nodelistStock xmldom.DOMNodeList;
nodelistStockChild xmldom.DOMNodeList;
stock_code char(6);--stock欄位
stock_name varchar2(30);--stockname欄位
stock_shortname varchar(30);--stockshortname欄位
stock_buydate date;--stockbuydate欄位
recordCountOuter number;--儲存xml文件中stock元素的個數
quantity exception;
begin

document:=xmlparser.parse(fileName);--解析xml文件
subelement:=xmldom.getDocumentElement(document);--獲得根元素
nodelistStock:=xmldom.getElementsByTagName(subelement,'Stock');
recordCountOuter:=xmldom.getLength(nodelistStock);
for outerCycle in 0..recordCountOuter-1 loop--迴圈記錄
nodelistStockChild:=xmldom.getChildNodes(xmldom.item(nodelistStock,outerCycle));
if xmldom.getLength(nodelistStockChild)<>4 then
raise quantity;
end if;
stock_code:=xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item(nodelistStockChild,0)));
stock_name:=xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item(nodelistStockChild,1)));
stock_shortname:=xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item(nodelistStockChild,2)));
stock_buydate:=to_date(xmldom.getNodeValue(xmldom.getFirstChild(xmldom.item(nodelistStockChild,3))),'yyyy-fmMM-fmDD HH24:MI:SS');
insert into stockmarket values(stock_code,stock_name,stock_shortname,stock_buydate);
end loop;
commit;
exception
when quantity then
raise_application_error(-20010,'請核對該xml文件與資料庫表Stockmarket的結構是否一致,'
||chr(10)||'若仍不能解決問題,請與系統管理員聯絡!');
end;

匯出:
/************************************************************************************************************
儲存過程名稱:up_exptoxml
引數1:XMLfilepath in varchar2 接收將要生成的檔名(可帶路徑)
引數2:sqlQuery in varchar2 接收使用者輸入的查詢字串,預設值為:"select * from stockmarket"
引數3:flag in varchar2 標誌位,說明第二個引數的來源(即由使用者輸入還是來自於檔案)預設值:
"",即由使用者輸入
使用方法:
1、預設方式:exec up_exptoxml(xmlfilepath) //將stockmarket表中的資料全部取出
儲存到引數xmlfilepath指定的檔案中
2、使用者指定查詢語句方式:
//將使用者指定的查詢語句所生成的結果集儲存到引數xmlfilepath所指定的檔案中
1)exec up_exptoxml(xmlfilepath,'select stockname,buydate from stockmarket')

//如果使用者認為查詢語句過長,直接輸入不方便,也可以將語句儲存成*.txt檔案,
//儲存過程執行方式如下:
2)exec up_exptoxml(xmlfilepath,'filepath,filename','file');
該方式下儲存過程將指定目錄,指定檔案中的sql語句讀出並執行,將所生成的結果集儲存到引數xmlfilepath
所指定的檔案中
功能:按照使用者要求將查詢結果儲存為xml檔案
************************************************************************************************************/
create or replace procedure up_exptoxml(XMLfilepath in varchar2, sqlQuery varchar2:='select * from stockmarket',flag varchar2:='sql') is
sqlstr_from_file clob;--儲存sql查詢字串
document xmldom.DOMDocument;--文件物件
rootelement xmldom.DOMElement;--根元素
stockRecord xmldom.DOMElement;--記錄
stockfield xmldom.DOMElement;--欄位
l_cursor integer;--儲存遊標變數返回值
l_col_cot integer;--遊標所包含的列數
l_desc_tab dbms_sql.desc_tab;--定義desc_tab型別的集合
tempfield dbms_sql.Varchar2_Table;--定義Varchar2_Table型別的集合
tempdate dbms_sql.Date_Table;--定義Date_Table型別的集合
tempnode xmldom.DOMNode;--定義臨時節點
text xmldom.DOMText;--定義文字節點
executenum integer;--儲存遊標執行返回值
--fieldvalue varchar2(50);
sqlfile utl_file.file_type;
parameter exception;--自定義異常
begin
if upper(flag)<>'SQL'and upper(flag)<>'FILE' then
raise parameter;--如果flag引數不為上述兩個選項,則丟擲引數異常
elsif upper(flag)='SQL' then
sqlstr_from_file:=sqlQuery;
else
--呼叫儲存過程以讀取檔案中存放的sql查詢字串
readFile(sqlQuery,sqlstr_from_file);
end if;
l_cursor:=dbms_sql.open_cursor;
dbms_sql.parse(l_cursor,sqlstr_from_file,dbms_sql.native);--解析遊標

dbms_sql.describe_columns(l_cursor,l_col_cot,l_desc_tab);--獲取列描述資訊
for def in 1..l_col_cot loop
if l_desc_tab(def).col_type=1 then
tempfield(def):='';--初始化集合元素
dbms_sql.define_column(l_cursor,def,tempfield(def),50);--定義列
else
tempdate(def):=sysdate;--初始化集合元素
dbms_sql.define_column(l_cursor,def,tempdate(def));--定義列
end if;
end loop;
executenum:=dbms_sql.execute(l_cursor);--執行遊標

document:=xmldom.newDOMDocument;--生成文件物件
rootelement:=xmldom.createElement(document,'StockTable');--生成根元素
loop--迴圈結果集(列方向)
if dbms_sql.fetch_rows(l_cursor)>0 then
stockrecord:=xmldom.createElement(document,'Stock');--建立臨時記錄元素
for i in 1..l_col_cot loop--(迴圈列,行方向)
stockfield:=xmldom.createElement(document,l_desc_tab(i).col_name);--建立欄位元素
if l_desc_tab(i).col_type=1 then--col_type=1 表示varchar2型別
--dbms_sql.define_column(l_cursor,i,tempfield(i),50);
dbms_sql.column_value(l_cursor,i,tempfield(i));
text:=xmldom.createTextNode(document,tempfield(i));
else --col_type=12 表示date型別
--dbms_sql.define_column(l_cursor,i,tempdate(i));
dbms_sql.column_value(l_cursor,i,tempdate(i));
text:=xmldom.createTextNode(document,to_char(tempdate(i),'yyyy-mm-dd HH24:MI:SS'));
end if;
--將文字節點新增到欄位節點
tempnode:=xmldom.appendChild(xmldom.makeNode(stockfield),xmldom.makeNode(text));
--將欄位節點新增到記錄節點
tempnode:=xmldom.appendChild(xmldom.makeNode(stockrecord),xmldom.makeNode(stockfield));
end loop;
--將記錄節點新增到根節點
tempnode:=xmldom.appendChild(xmldom.makeNode(rootelement),xmldom.makeNode(stockrecord));
else
--no more row to copy
dbms_sql.close_cursor(l_cursor);--遍歷遊標結束,關閉遊標
exit;
end if;
end loop;
--將根節點新增到文件
tempnode:=xmldom.appendChild(xmldom.makeNode(document),xmldom.makeNode(rootelement));
xmldom.setVersion(document,'1.0');
xmldom.writeToFile(document,XMLfilepath);
exception
when parameter then
raise_application_error(-20004,'必須以"sql"或者"file"方式指定sql語句的來源');
when others then
if dbms_sql.is_open(l_cursor) then
dbms_sql.close_cursor(l_cursor);
end if;
raise_application_error(-20005,'未知異常,遊標已關閉!');
end up_exptoxml;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9099175/viewspace-917605/,如需轉載,請註明出處,否則將追究法律責任。

相關文章