說明:入參xml_in 爲xml字符串
出參package.cursor爲自定義包的類型
變量ZH_KSDMTYPE爲自定義表類型,該類型定義時需要實現類型體(type bodies)
CREATE OR REPLACE PROCEDURE ZH_PLATFORM_DEPART (xml_in IN CLOB, v_cur OUT package.cursor)
AS
---xml解析爲doc
xmlp xmlparser.parser;
xml_doc xmldom.DOMDocument;
doc_node xmldom.DOMNode;
doc_nodelist xmldom.DOMNodeList;
doc_len number;
---信息
Info_Nodel xmldom.DOMNodeList;
Info_No xmldom.DOMNode;
Info_Len number;
test_xml CLOB;
---子元素
child_node xmldom.DOMNode;
child_NodeList xmldom.DOMNodeList;
child_len number;
nnm xmldom.DOMNamedNodeMap; --暫存row數據map
v_coluValue varchar2(4000); ---最小節點值
v_nodeName varchar2(100); --最小節點名稱
n_maxFid number(18); --日誌ID
Log_ygbh VARCHAR2(20);
n_rollback number(2); --回滾點
v_Sqlerrm varchar2(1000); --錯誤
Ret_MSG varchar2(1000);
---自定義錯誤 20000 操作成功 20001 校驗失敗 20002 不能爲空 20003 已存在 20004 獲取失敗
EXCEPTION_ERR EXCEPTION;
ERR_TEXT varchar2(1000);---錯誤
ERR_CODE number(18); ---自定義錯誤號:20000-20999
--科室代碼表結構變量
Zh_KSDM ZH_KSDMTYPE :=ZH_KSDMTYPE(0);
BEGIN
--測試用
select clob_xml into test_xml from test_clob where clob_id=1;
--先保存到日誌表
--獲取主鍵
gf_get_max('ZH_PROXML',1,n_maxFid);
n_rollback :=1;
Savepoint tran_one; --開始事務
insert into ZH_PROXML(fid,czgh,czdate,funcode,funname,fxmlin) --,fxmlin,fxmlout,mzhm
values(n_maxFid,'回寫',sysdate,'B0004','此爲日誌',test_xml);
commit ;
n_rollback :=0;
--xml解析
xmlp := xmlparser.newparser;
xmlparser.parseclob(xmlp,test_xml); --- 測試 test_xml 正式 xml_in
--xml轉換爲doc
xml_doc := xmlparser.getDocument(xmlp);
xmlparser.freeparser(xmlp);
Info_Nodel := xmldom.getElementsByTagName(xml_doc,'INFO');
Info_Len :=xmldom.getLength(Info_Nodel);
--取出第一個 INFO
Info_No:=xmldom.item(Info_Nodel,0);
Info_Nodel := xmldom.getChildNodes(Info_No);
Info_Len := xmldom.getLength(Info_Nodel);
for w in 0.. Info_Len-1 loop
Info_No:=xmldom.item(Info_Nodel,w);
v_coluValue := xmldom.getNodeValue(xmldom.getFirstChild(Info_No));
v_nodeName :=xmldom.getNodeName(Info_No);
if v_nodeName = 'INFOID' then
IF v_coluValue <> 'B0004' then
ERR_TEXT := 'XML校驗失敗!';
ERR_CODE :=20001;
raise EXCEPTION_ERR;
end if;
end if;
if v_nodeName = 'EMPNUM' then
Log_ygbh :=v_coluValue;
end if;
end loop;
---取出所有row元素
doc_nodelist := xmldom.getElementsByTagName(xml_doc,'ROW');
doc_len :=xmldom.getLength(doc_nodelist);
n_rollback :=2;
Savepoint tran_two; --開始事務
for i in 0.. doc_len-1 loop
--取出第i個row元素
doc_node:=xmldom.item(doc_nodelist,i);
child_NodeList := xmldom.getChildNodes(doc_node);
child_len := xmldom.getLength(child_NodeList);
for k in 0..child_len-1 loop
--取出第i 個結點
child_node := xmldom.item(child_NodeList,k);
--節點名稱
v_nodeName :=xmldom.getNodeName(child_node);
--節點值
v_coluValue := xmldom.getNodeValue(xmldom.getFirstChild(child_node));
if v_nodeName = 'DEPARTNUM' then --科室代碼
end if;
END LOOP;
---更新或插入
END LOOP;
v_Sqlerrm:=Sqlerrm||dbms_utility.format_error_backtrace();
update ZH_PROXML set msg=v_Sqlerrm where fid = n_maxFid;
ERR_TEXT := '成功!';
ERR_CODE :=20000;
Ret_MSG := to_char(ERR_CODE)||'-'||ERR_TEXT; ---Log_ygbh
update ZH_PROXML set sqlerr=v_Sqlerrm ,msg=Ret_MSG,czgh=nvl(Log_ygbh,czgh) where fid = n_maxFid;
commit;
xmldom.freeDocument(xml_doc);
Open v_cur For
Select ERR_TEXT As msg,ERR_CODE as msgcode From dual;
return;
EXCEPTION
when EXCEPTION_ERR then
if n_rollback = 1 then
rollback to tran_one;
else
if n_rollback = 2 then
rollback to tran_two;
end if;
end if;
Ret_MSG := to_char(ERR_CODE)||'-'||ERR_TEXT;
update ZH_PROXML set msg=Ret_MSG,czgh=nvl(Log_ygbh,czgh) where fid = n_maxFid;
commit;
Open v_cur For
Select ERR_TEXT As msg,ERR_CODE as msgcode From dual;
return;
When others Then
if n_rollback = 1 then
rollback to tran_one;
else
if n_rollback = 2 then
rollback to tran_two;
end if;
end if;
v_Sqlerrm:=Sqlerrm||dbms_utility.format_error_backtrace();
ERR_CODE :=sqlcode;
update ZH__PROXML set sqlerr=v_Sqlerrm where fid = n_maxFid;
Open v_cur For
Select v_Sqlerrm As msg,ERR_CODE as msgcode From dual;
return;
END;