Overview
The following article shows some of the possibilities how XML documents can be created with PL/SQL and Oracle 8i or 9i. The discussed topics are:
XMLGEN Package
XML-SQL Utility for PL/SQL
XMLDOM Package
The examples use the well known tables DEPT (the master table) and EMP (the detail table): Every employee has exactly one department assigned. One department has no, one, or more employees.
SELECT deptno, dname FROM dept;
DEPTNO DNAME
---------- --------------
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONSSELECT empno, ename, deptno FROM emp;
EMPNO ENAME DEPTNO
---------- ---------- ----------
7369 SMITH 20
7499 ALLEN 30
7521 WARD 30
7566 JONES 20
7654 MARTIN 30
7698 BLAKE 30
7782 CLARK 10
7788 SCOTT 20
7839 KING 10
7844 TURNER 30
7876 ADAMS 20
7900 JAMES 30
7902 FORD 20
7934 MILLER 10
XMLGEN Package
The simplest way to generate an XML document is the usage of the package XMLGEN. The function getXml() takes the parameters for the SQL query and the meta data type (such as DTD) and returns a CLOB containing the XML document.
SELECT xmlgen.getXml(
'SELECT empno "EMP_NO"
, ename "NAME"
, deptno "DEPT_NO"
FROM emp
WHERE deptno = 10'
, 0
) FROM dual;<?xml version = '1.0'?>
<ROWSET>
<ROW num="1">
<EMP_NO>7782</EMP_NO>
<NAME>CLARK</NAME>
<DEPT_NO>10</DEPT_NO>
</ROW>
<ROW num="2">
<EMP_NO>7839</EMP_NO>
<NAME>KING</NAME>
<DEPT_NO>10</DEPT_NO>
</ROW>
<ROW num="3">
<EMP_NO>7934</EMP_NO>
<NAME>MILLER</NAME>
<DEPT_NO>10</DEPT_NO>
</ROW>
</ROWSET>The result is a root element named ROWSET, which contains a list of ROW-elements. Each ROW-element has the row number as attribute and each ROW-element contains the elements EMP_NO, NAME, and DEPT_NO. Note that the element names of the ROW-elements are slightly different from the column names of the EMP table!
Using XML-SQL Utility (XSU)
XML-SQL Utility (XSU) provides a simple way of achieving data transformation by mapping any SQL query to XML and vice versa. XSU provides the basic functionality to get and put data to and from a database.
The DBMS_XMLQUERY and DBMS_XMLSAVE are two packages that support XML generation and storage through XML. Here we will focus on XML generation.
Generating XML by invoking getXML() function results in a CLOB that contains the XML document. A context handle needed in most subsequent calls is created in the first step.
DECLARE
queryCtx dbms_xmlquery.ctxType;
result CLOB;
BEGIN
-- set up the query context
queryCtx := dbms_xmlquery.newContext(
'SELECT empno "EMP_NO"
, ename "NAME"
, deptno "DEPT_NO"
FROM emp
WHERE deptno = :DEPTNO'
);If the DTD or XML schema definition has explicitly defined tag names others than the column names then you can change the ROW and ROWSET tag names easily:
dbms_xmlquery.setRowTag(
queryCtx
, 'EMP'
);
dbms_xmlquery.setRowSetTag(
queryCtx
, 'EMPSET'
);Before executing the query you must bind the values to the SQL statement. The named bind variables have to start with a ’:’ in front.
dbms_xmlquery.setBindValue(
queryCtx
, 'DEPTNO'
, 10
);Ok, now you are ready to run the query and generate the XML result as CLOB. A simple procedure printClobOut() supports printing out a CLOB to screen. Finally the query handle must be closed to free the resources.
result := dbms_xmlquery.getXml(queryCtx);
printClobOut(result);
dbms_xmlquery.closeContext(queryCtx);
END;
/The result is something like
<?xml version = '1.0'?>
<EMPSET>
<EMP num="1">
<EMP_NO>7782</EMP_NO>
<NAME>CLARK</NAME>
<DEPT_NO>10</DEPT_NO>
</EMP>
<EMP num="2">
<EMP_NO>7839</EMP_NO>
<NAME>KING</NAME>
<DEPT_NO>10</DEPT_NO>
</EMP>
<EMP num="3">
<EMP_NO>7934</EMP_NO>
<NAME>MILLER</NAME>
<DEPT_NO>10</DEPT_NO>
</EMP>
</EMPSET>Moreover you can use further functionality provided by the DBMS_XMLQUERY such as
Paginating by using setMaxRows() and setSkipRows().
Setting and applying stylesheets by using setStylesheetHeader() and useStylesheet(). The utility generates the XML document, calls the parser, applies the stylesheet, and generates the result which is a huge performance win.
The package DBMS_XMLQUERY supports XML generation. In a similar way you can use DBMS_XMLSAVE to store XML data directly in the database. Possible operations are insertXML(), updateXML(), and deleteXML().
XMLDOM Package
The XMLDOM package implements the Document Object Model Interface (DOM Interface) as defined by W3C XML recommendations. Some of the interfaces are:
DOM Attribute interface
DOM Document interface
DOM DocumentType interface
DOM DOMImplementation interface
DOM Element interface
DOM Node interface
DOM NodeList interface
DOM Notation interface
DOM ProcessingInstruction interface
DOM Text interface
Let’s go through a simple example to discuss the usage of the XMLDOM package. Give special privileges to the user running this code. A private synonym simplifies the access to the package. For example, for user scott:
GRANT javauserpriv to scott;
GRANT javasyspriv to scott;
GRANT EXECUTE ON xmldom TO scott;
CREATE SYNONYM scott.xmldom FOR SYS.xmldom;In the declaration section, you need a set of DOM references. The DOMDocument handle is the most important. It will be used in most subsequent calls. Moreover you need different DOM node handles to reference the main node, the root node, the user node, and the item node for each element. The cursor selects the employees for a given department.
DECLARE
doc xmldom.DOMDocument;
main_node xmldom.DOMNode;
root_node xmldom.DOMNode;
user_node xmldom.DOMNode;
item_node xmldom.DOMNode;
root_elmt xmldom.DOMElement;
item_elmt xmldom.DOMElement;
item_text xmldom.DOMText;
CURSOR get_users(p_deptno NUMBER) IS
SELECT empno
, ename
, deptno
, rownum
FROM emp
WHERE deptno = p_deptno;First of all you create a new document handle. Next you create the main node for this document. The root element is named EMPSET and appended as child node to the main node. The returned handle is used as root node for subsequent calls.
BEGIN
doc := xmldom.newDOMDocument;
main_node := xmldom.makeNode(doc);
root_elmt := xmldom.createElement(
doc
, 'EMPSET'
);
root_node := xmldom.appendChild(
main_node
, xmldom.makeNode(root_elmt)
);For every record found in the query a new element named EMP is created. Analogue to the previous samples, the row number is added as attribute to the element. This element is appended as child node to the root node. The returned handle is used as user node for subsequent calls.
FOR get_users_rec IN get_users(10) LOOP
item_elmt := xmldom.createElement(
doc
, 'EMP'
);
xmldom.setAttribute(
item_elmt
, 'num'
, get_users_rec.rownum
);
user_node := xmldom.appendChild(
root_node
, xmldom.makeNode(item_elmt)
);Now the text elements can be added to the DOM document. In the first step a new element named EMP_NO is created. This element is appended as child node to the user node. In the second step a text node is created which contains the record data, in this case the employee number. This text node is appended as child node to the item node.
item_elmt := xmldom.createElement(
doc
, 'EMP_NO'
);
item_node := xmldom.appendChild(
user_node
, xmldom.makeNode(item_elmt)
);
item_text := xmldom.createTextNode(
doc
, get_users_rec.empno
);
item_node := xmldom.appendChild(
item_node
, xmldom.makeNode(item_text)
);The same can be done with the text elements NAME and DEPT_NO.
After all records have been processed and all data has been loaded into the DOM document it can be e.g. filed out and its resources can be released:
END LOOP;
xmldom.writeToFile(
doc
, '/tmp/xml/docSample.xml'
);
xmldom.freeDocument(doc);
END;
/Note that the XMLDOM package is able to write the XML file in every location accessible by OS user oracle, regardless of the current initialisation parameter UTL_FILE_DIR. The resulting file contains the following lines:
<?xml version = '1.0' encoding = 'UTF-8'?>
<EMPSET>
<EMP num="1">
<EMP_NO>7782</EMP_NO>
<NAME>CLARK</NAME>
<DEPT_NO>10</DEPT_NO>
</EMP>
<EMP num="2">
<EMP_NO>7839</EMP_NO>
<NAME>KING</NAME>
<DEPT_NO>10</DEPT_NO>
</EMP>
<EMP num="3">
<EMP_NO>7934</EMP_NO>
<NAME>MILLER</NAME>
<DEPT_NO>10</DEPT_NO>
</EMP>
</EMPSET>Even if the usage of XMLDOM package seems to be complex at the beginning, the structure of the DOM document is build up in a simple way: Every element or attribute must be added as a node to a parent node. The same approach with equivalent methods is used within Java and its XML implementation.
For easier handling of the common functionality you may write your own XML library to simplify for example adding text nodes to parent nodes.
Some limitations: Keep in mind, that the whole DOM tree is kept in memory until the document is freed. Depending on database memory configuration the total number of nodes is limited, e.g. with JAVA_POOL_SIZE of 10’0000'000 bytes we could add up to 20'000 nodes.
Another limitation is a memory leak in the Java implementation of the DOM interface and XML parser. This bug is known under Sun Solaris and can be fixed with Oracle 8.1.7.3 and bug fix 2104071 or with Oracle 9.2.
Conclusion
The XMLGEN package can be used for simple XML document generation. The data can be fetched from a single SQL statement.
XSU with the two packages DBMS_XMLQUERY and DBMS_XMLSAVE supports XML generation and storage through XML. Additional functionality allows the developer to bind variables, to paginate the result set, or to apply stylesheets directly.
The most sophisticated approach is the XMLDOM package. Here you have the full flexibility provided by the DOM interface. Every given DTD or XML schema definition can be implemented using complex elements, attributes and more.
Links and Documents
Further articles about generating XML documents with PL/SQL
Oracle XML Reference Guide
Oracle Application Developer's Guide - XML
Download Scripts
相关推荐
If you are interested in creating your own Plug-Ins you should read the Plug-In documentation and demo's in the PlugInDoc directory included with the PL/SQL Developer download. If you have created a ...
在深入探讨《pl/sql学习文档》的精粹之前,我们先来明确一下PL/SQL(Procedural Language for SQL)的定义与重要性。PL/SQL是Oracle数据库为提升SQL的功能性和灵活性而开发的一种过程化语言。它允许开发者在数据库...
#### 八、创建和修改非PL/SQL对象(Creating and Modifying Non-PL/SQL Objects) - **表定义编辑器**:介绍如何使用表定义编辑器来创建和修改表结构。 - **序列定义编辑器**:教授如何管理序列对象。 - **同义词...
- **SQL*Plus**: A command-line tool for interacting with the Oracle database, executing SQL commands, and running PL/SQL scripts. - **JDeveloper**: An integrated development environment (IDE) provided...
plsql developer7最新中文参考手册
For these file control operations PL/SQL Developer relies on a 3rd party shell extension that must be installed on your system. In the screenshots above “GIT Extensions” has been used. Worksets A ...
9. **Les09-Creating Stored Procedures and Functions**:最后,你将学习如何创建和调用存储过程和函数,这是PL/SQL中复用代码和实现业务逻辑的关键。 10. **Intro.ppt**:这个可能是介绍性的幻灯片,可能会涵盖...
在Web开发领域,"Creating Web Pages with Asynchronous JavaScript and XML"这一主题主要涉及AJAX(Asynchronous JavaScript and XML)技术的使用。AJAX允许开发者在不刷新整个网页的情况下,实现页面部分数据的...
Preface Acknowledgements 1 XML for Data 2 XML Protocols ...Creating New XML Documents with DOM 11 The Document Object Model Core 12 The DOM Traversal Module 13 Output from DOM ...
PL/SQL Parser did not process double quoted identifiers with quotes and comments correctly Code Assistant did not work for aliases for table names in double quotes Right-click on a quoted "OWNER"....
* A robust programming editor that embeds the powerful EditRocket code editor that supports 20 programming languages including SQL, PL/SQL, TransactSQL, SQL PL, HTML, XML, and more. * Export Tool - ...
This is your one-stop guide to mastering the XML metalanguage and JSON data format along with significant Java APIs for parsing and creating XML/JSON documents (and more). The first six chapters focus...
Beginning Transact-SQL with SQL Server 2000 and 2005 byPaul TurleyandDan Wood Wrox Press 2006 (594 pages) ISBN:076457955X Prepare for the ever-increasing demands of programming....
以上是对Oracle SQL教程中的关键知识点的详细解析,涵盖了关系数据库的基本概念、SQL的基本操作、数据的存储与检索、PL/SQL的应用以及数据库设计等多个方面。通过这些知识点的学习,可以帮助读者更好地理解和应用...
Long gone are the days of mobile apps with a static UI squished on a tiny screen. Today's users expect mobile apps to be dynamic and highly interactive. They expect an app to look fantastic when they ...