说明:入参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;
该Oracle存储过程接收一个XML字符串作为输入,并将其解析为DOM文档。过程中涉及到XML校验、数据提取、日志记录以及事务管理。通过遍历XML节点,将数据处理并更新到ZH_KSDMTYPE类型的自定义表中。

298

被折叠的 条评论
为什么被折叠?



