1、ORACLE存储过程返回XML的处理目前公司的报表显示方式是:oracle返回数据集-JAVA组XML-Delphi 展现由于JAVA组XML会耗费相当多的时间和性能,从而影响客户体验考虑由oracle直接返回一个前台Delphi可解析的XML格式,从而减少JAVA组XML所带来的带宽和性能的耗费显示样式: 0 null 操作步骤:1. 设置UTL_FILE参数SQL show parameter UTL_FILE;NAME TYPE VALUE- - -utl_file_dir string 2.查看系统是以何种参数文件启动SQL show parameter spfile;NAME TYP
2、E VALUE- - -spfile string E:ORACLEPRODUCT10.2.0DB_1DATABASESPFILEORCL.ORA3.设置UTL_FILE值(注意如果气动方式是ORA可以直接去文件里面修改)alter system set utl_file_dir=d:log scope=spfile4.重启服务查看是否设置成功SQL show parameter UTL_FILENAME TYPE VALUE- - -utl_file_dir string d:log5.授权给其他用户GRANT EXECUTE ON utl_file TO nick;6.写存储过程CREAT
3、E OR REPLACE PROCEDURE OUTPUTPEOPLE1(sqlStr VARCHAR2, file_path VARCHAR2, files varchar2) AS personRow TB_TMPXML%ROWTYPE; -获取游标的行变量 TYPE person_cur IS REF CURSOR; -自定义REF游标 cur person_cur; tempSql varchar2(500) := SELECT * FROM dept ; -初始的查询语句 doc xmlDom.DOMDocument := xmldom.newDOMDocument; - 创建文档对
4、象 main_node xmlDom.DOMNode := xmldom.makeNode(doc); - 获得文档节点 root_elmt xmlDom.DOMElement := xmldom.createElement(doc, Information); - 创建根元素 i number; -动态获取当前第几列 V_COLUMN_NAME varchar2(100); -动态获取当前列名字 -= -以下定义元素 code_elmt xmlDom.DOMElement; -CODE节点 descript_elmt xmlDom.DOMElement; -descript_elmt UNK
5、NOWN_elmt xmlDom.DOMElement; -UNKNOWN_elmt resultst_elmt xmlDom.DOMElement; rs_elmt xmlDom.DOMElement; -= -以下定义节点 root_node xmlDom.DOMNode; -根 code_node xmlDom.DOMNode; -定义CODE节点 descript_node xmlDom.DOMNode; -定义CODE节点 UNKNOWN_node xmlDom.DOMNode; -UNKNOWN_node results_node xmlDom.DOMNode; rs_node x
6、mlDom.DOMNode;BEGIN -附加查询条件 tempSql := sqlStr; select count(1) into i from all_tables d where d.TABLE_NAME = TB_TMPXML; if i 0 then execute immediate drop table TB_TMPXML; end if;-手动创建标识列tempSql:=select rownum id,d.* from (|tempSql|) d;-保存到临时表 execute immediate create table TB_TMPXML as | tempSql; -
7、动态创建索引 execute immediate create index index_TB_TMPXML_id on TB_TMPXML(id) ; - 把Information作为根节点 root_node := xmldom.appendChild(main_node, xmldom.makeNode(root_elmt); -创建CODE code_elmt := xmldom.createElement(doc, CODE); - 添加到把Information作为根节点节点下 code_node := xmldom.appendChild(root_node, xmldom.mak
8、eNode(code_elmt); code_node := xmldom.appendChild(code_node, xmlDom.makeNode(xmldom.createTextNode(doc, 0); -=- -null descript_elmt := xmldom.createElement(doc, description); - 添加到把Information作为根节点节点下 descript_node := xmldom.appendChild(root_node, xmldom.makeNode(descript_elmt); descript_node := xml
9、dom.appendChild(descript_node, xmlDom.makeNode(xmldom.createTextNode(doc, 0); -results resultst_elmt := xmldom.createElement(doc, results); results_node := xmldom.appendChild(root_node, xmldom.makeNode(resultst_elmt); results_node := xmldom.appendChild(results_node, xmlDom.makeNode(xmldom.createText
10、Node(doc, 0); rs_elmt := xmldom.createElement(doc, rs); rs_node := xmldom.appendChild(root_node, xmldom.makeNode(rs_elmt); -加一个属性 -向PERSON节点加入属性PERSONID xmlDom.SETATTRIBUTE(rs_elmt, PERSONID, recordset); xmlDom.SETATTRIBUTE(rs_elmt, tbname, UNKNOWN); xmlDom.SETATTRIBUTE(rs_elmt, fields, | files | );
11、 -打开游标 OPEN cur FOR select * from TB_TMPXML; -遍历游标 LOOP FETCH cur INTO personRow; EXIT WHEN cur%NOTFOUND; -添加UNKNOWN_node UNKNOWN_elmt := xmldom.createElement(doc, UNKNOWN); UNKNOWN_node := xmldom.appendChild(rs_node, xmldom.makeNode(UNKNOWN_elmt); - xmlDom.SETATTRIBUTE(UNKNOWN_elmt, PERSONID,person
12、Row.D_ID); -循环添加属性 i := 2; for cur in (SELECT REGEXP_SUBSTR(files, +, 1, l_count) AS nodename FROM dual, (SELECT LEVEL l_count FROM DUAL CONNECT BY LEVEL = 100) WHERE l_count = LENGTH(files) - LENGTH(REPLACE(files, ) + 1) loop -获取当前行的列名 execute immediate select COLUMN_NAME from user_tab_cols d where
13、 d.TABLE_NAME=TB_TMPXML and d.COLUMN_ID= | i | into V_COLUMN_NAME; tempSql := select | V_COLUMN_NAME | from tb_tmpxml where id=|personRow.id; execute immediate tempSql into V_COLUMN_NAME; xmlDom.SETATTRIBUTE(UNKNOWN_elmt, (substr(cur.nodename, 0, instr(cur.nodename, :) - 1), V_COLUMN_NAME); i := i + 1; end loop; END LOOP; CLOSE cur; -写入硬盘 - xmlDom.writeToFile(doc,file_path,GBK); xmlDom.writeToFile(doc, d:log | / | qudjdian.xml, GBK);EXCEPTION WHEN OTHERS THEN DBMS_output.PUT_LINE(SQLERRM);END OUTPUTPEOPLE1;/