13 Using the XML SQL Utility
An explanation is given of how to use the Extensible Markup Language (XML) SQL Utility (XSU).
Topics:
- Introduction to the XML SQL Utility (XSU)
XML SQL Utility (XSU) is an Oracle XML Developer's Kit (XDK) component that lets you transfer XML data using Oracle SQL statements. - Using the XML SQL Utility: Overview
Topics here include basic XSU use, installing XSU, running the XSU demo programs, and using the XSU command-line utility. - Programming with the XSU Java API
Topics here include using OracleXMLQuery and OracleXMLSave to perform various operations, and handling XSU Java exceptions. - Programming with the XSU PL/SQL API
Topics here describe programming tasks that make use of the XSU PL/SQL API. - Tips and Techniques for Programming with XSU
This section provides tips and techniques for writing programs with XSU.
13.1 Introduction to the XML SQL Utility (XSU)
XML SQL Utility (XSU) is an Oracle XML Developer's Kit (XDK) component that lets you transfer XML data using Oracle SQL statements.
You can use XML SQL Utility (XSU) to perform these tasks:
-
Transform data in object-relational database tables or views into XML. XSU can query the database and return the result set as an XML document.
-
Extract data from an XML document and use canonical mapping to insert the data into a table or a view or update or delete values of the appropriate columns or attributes.
Topics:
- Prerequisites for Using the XML SQL Utility (XSU)
Prerequisites for using the XML SQL Utility (XSU) are covered. - XSU Features
The main features provided by XML SQL Utility (XSU) are described. - XSU Restrictions
Some restrictions for using XSU are described.
13.1.1 Prerequisites for Using the XML SQL Utility (XSU)
Prerequisites for using the XML SQL Utility (XSU) are covered.
This section assumes that you are familiar with these technologies:
-
Oracle Database structured query language (SQL). XSU transfers XML to and from a database through
SELECTstatements and data manipulation language (DML). -
Procedural Language/Structured Query Language (PL/SQL). XDK supplies a PL/SQL application programming interface (API) for XSU that mirrors the Java API.
-
Java Database Connectivity (JDBC). Java applications that use XSU to transfer XML to and from a database require a JDBC connection.
13.1.2 XSU Features
The main features provided by XML SQL Utility (XSU) are described.
XSU:
-
Dynamically generates document type definitions (DTDs) or XML schemas.
-
Generates XML documents in their string or Document Object Model (DOM) representations.
-
Performs simple transformations during generation such as modifying default tag names for each
<ROW>element. You can also register an XSL transformation that XSU applies to the generated XML documents as needed. -
Generates XML as a stream of Simple API for XML (SAX2) callbacks.
-
Supports XML attributes during generation, which enables you to specify that a particular column or group of columns maps to an XML attribute instead of an XML element.
-
Allows SQL-to-XML-tag escaping. Sometimes column names are not valid XML tag names. To avoid this problem you can either alias all the column names or turn on tag escaping.
-
Supports
XMLTypecolumns in objects or tables. -
Inserts XML into relational database tables or views. When given an XML document, XSU can also update or delete records from a database object.
13.1.3 XSU Restrictions
Some restrictions for using XSU are described.
-
XSU can store data only in a single table. You can store XML across tables, however, by using the Oracle Extensible Stylesheet Language Transformation (XSLT) processor to transform a document into multiple documents and inserting them separately. You can also define views over multiple tables and perform insertions into the views. If a view is nonupdatable (because of complex joins), then you can use
INSTEADOFtriggers over the views to perform the inserts. -
You cannot use XSU to load XML data stored in attributes into a database schema, but you can use an XSLT transformation to change the attributes into elements.
-
By default XSU is case-sensitive. You can either use the correct case, or specify that case is to be ignored.
-
XSU cannot generate a relational database schema from an input DTD.
-
Inserting into
XMLTypetables using XSU is not supported.XMLTypecolumns are supported.
13.2 Using the XML SQL Utility: Overview
Topics here include basic XSU use, installing XSU, running the XSU demo programs, and using the XSU command-line utility.
Topics:
- Using XSU: Basic Process
The basic process of using XSU is described. - Installing XSU
XSU is included as part of Oracle Database, along with the other XDK utilities. - Running the XSU Demo Programs
Demo programs for XSU are included in$ORACLE_HOME/xdk/demo/java/xsu. - Using the XSU Command-Line Utility
XDK includes a command-line Java interface for XSU. XSU command-line options are provided through the Java classOracleXML.
13.2.1 Using XSU: Basic Process
The basic process of using XSU is described.
XSU is accessible through Java classes OracleXMLQuery and OracleXMLSave in package oracle.xml.sql.query. Use class OracleXMLQuery to generate XML from relational data and class OracleXMLSave to perform DML.
You can write these types of XSU applications:
-
Java programs that run inside the database and access the internal XSU Java API
-
Java programs that run on the client and access the client-side XSU Java API
-
PL/SQL programs that access XSU through PL/SQL packages
Topics:
- Generating XML with the XSU Java API: Basic Process
ClassOracleXMLQuerymakes up the XML generation part of the XSU Java API. - Performing DML with the XSU Java API: Basic Process
Use theOracleXMLSaveclass to insert, update, and delete XML in the database. - Generating XML with the XSU PL/SQL API: Basic Process
The XSU PL/SQL API reflects the Java API in the generation and storage of XML documents from and to a database. PackageDBMS_XMLQueryreflects the methods in Java classOracleXMLQuery. - Performing DML with the PL/SQL API: Basic Process
DBMS_XMLSaveis the PL/SQL package that reflects the methods in Java classOracleXMLSave. This package has a context handle associated with it. You create a context by invoking a constructor-like function to get the handle, and then use the handle in all subsequent invocations.
13.2.1.1 Generating XML with the XSU Java API: Basic Process
Class OracleXMLQuery makes up the XML generation part of the XSU Java API.
Figure 13-1 shows the basic process for generating XML with XSU.
The basic steps in Figure 13-1 are:
13.2.1.2 Performing DML with the XSU Java API: Basic Process
Use the OracleXMLSave class to insert, update, and delete XML in the database.
Figure 13-2 shows the basic process.
Figure 13-2 Storing XML in the Database Using XSU

Description of "Figure 13-2 Storing XML in the Database Using XSU"
The basic steps in Figure 13-2 are:
-
Create a JDBC connection to the database. This step is identical to the first step described in Generating XML with the XSU Java API: Basic Process.
-
Create an XML save object and assign it a table on which to perform DML. Pass a table or view name to the constructor, as shown in this example:
OracleXMLSave sav = new OracleXMLSave(conn, "employees");
-
Specify the primary key columns. For example, this code specifies that
employee_idis the key column:String [] keyColNames = new String[1]; keyColNames[0] = "EMPLOYEE_ID"; sav.setKeyColumnList(keyColNames);
-
Configure the XML save object by invoking
OracleXMLSavemethods. This example specifies an update of thesalaryandjob_idcolumns:String[] updateColNames = new String[2]; updateColNames[0] = "SALARY"; updateColNames[1] = "JOB_ID"; sav.setUpdateColumnList(updateColNames); // set the columns to update
-
Invoke the
insertXML(),updateXML(), ordeleteXML()methods on theOracleXMLSaveobject. This example shows an update:// Assume that the user passes in this XML document as the first argument sav.updateXML(sav.getURL(argv[0]));
When performing the DML, XSU performs these tasks:
-
Parses the input XML document.
-
Matches element names to column names in the target table or view.
-
Converts the elements to SQL types and binds them to the appropriate statement.
-
-
Close the
OracleXMLSaveobject and deallocate all contexts associated with it, as shown in this example:sav.close();
See Also:
-
Oracle Database Java Developer’s Guide to learn about JDBC
-
Oracle Database XML Java API Reference to learn about
OracleXMLSave
-
13.2.1.3 Generating XML with the XSU PL/SQL API: Basic Process
The XSU PL/SQL API reflects the Java API in the generation and storage of XML documents from and to a database. Package DBMS_XMLQuery reflects the methods in Java class OracleXMLQuery.
Package DBMS_XMLQuery has a context handle associated with it. Create a context by invoking a constructor-like function to get the handle, and then use the handle in all subsequent invocations.
Note:
For improved performance, consider using the C-based DBMS_XMLGEN, which is written in C and built into the database, rather than DBMS_XMLQUERY.
XSU supports the XMLType data type. Using XSU with XMLType is useful if, for example, you have XMLType columns in objects or tables.
Generating XML results in a character large object (CLOB) that contains the XML document. To use DBMS_XMLQuery and the XSU generation engine, follow these basic steps:
13.2.1.4 Performing DML with the PL/SQL API: Basic Process
DBMS_XMLSave is the PL/SQL package that reflects the methods in Java class OracleXMLSave. This package has a context handle associated with it. You create a context by invoking a constructor-like function to get the handle, and then use the handle in all subsequent invocations.
To use DBMS_XMLSave, follow these basic steps:
For a model use the Java examples described in Programming with the XSU Java API.
13.2.2 Installing XSU
XSU is included as part of Oracle Database, along with the other XDK utilities.
XDK for Java Component Dependencies describes the XSU components and dependencies.
By default, the Oracle Universal Installer installs XSU on disk and loads it into the database. No user intervention is required. If you did not load XSU in the database when installing Oracle, you can install XSU manually as follows:
- Ensure that Oracle XML DB is installed (it is installed by default as part of Oracle Database).
- Load the
xsu12.jarfile into the database. This JAR file, which has a dependency onxdb.jarforXMLTypeaccess, is described in Table 3-1. - Run the
$ORACLE_HOME/rdbms/admin/dbmsxsu.sqlscript. This SQL script builds the XSU PL/SQL API.
As explained in Using XSU: Basic Process, you do not have to load XSU into the database to use it. XSU can reside in any tier that supports Java.
Topics:
- XSU in the Database
The typical architecture is shown for applications that use the XSU libraries installed in the database. - XSU in an Application Server
You can run XSU in an application server. - XSU in a Web Server
You can run XSU in a web server because the web server supports Java servlets.
13.2.2.1 XSU in the Database
The typical architecture is shown for applications that use the XSU libraries installed in the database.
Figure 13-3 illustrates this typical architecture. XML generated from XSU running in the database can be placed in advanced queues in the database to be queued to other systems or clients. You deliver the XML internally through stored procedures in the database or externally through web servers or application servers.
In Figure 13-3 all lines are bidirectional. Because XSU can generate and save data, resources can deliver XML to XSU running inside the database, which can then insert it in the appropriate database tables.
13.2.2.2 XSU in an Application Server
You can run XSU in an application server.
Your application architecture may require an application server in the middle tier. The application tier can be a database or an application server that supports Java programs.
You can generate XML in the middle tier from SQL queries or ResultSets for various reasons, for example, to integrate different JDBC data sources in the middle tier. In this case, you can install XSU in your middle tier, thereby enabling your Java programs to make use of XSU through its Java API.
Figure 13-4 shows a typical architecture for running XSU in a middle tier. In the middle tier, data from JDBC sources is converted by XSU into XML and then sent to web servers or other systems. Again, the process is bidirectional, which means that the data can be put back into the JDBC sources (database tables or views) with XSU. If a database is used as the application server, then you can use the PL/SQL front end instead of Java.
Figure 13-4 Running XSU in the Middle Tier

Description of "Figure 13-4 Running XSU in the Middle Tier"
13.2.2.3 XSU in a Web Server
You can run XSU in a web server because the web server supports Java servlets.
Figure 13-5 shows XSU running in a web server.
You can write Java servlets that use XSU. XSQL Servlet is a standard servlet provided by Oracle. It is built on top of XSU and provides a template-like interface to XSU functionality. To perform XML processing in the web server and avoid intricate servlet programming, you can use the XSQL Servlet.
See Also:
-
Oracle XML DB Developer’s Guide, especially the chapter on generating XML, for examples on using XSU with
XMLType -
Oracle Database XML Java API Reference to learn about the classes
OracleXMLQueryandOracleXMLSave -
Using the XSQL Pages Publishing Framework to learn about XSQL Servlet
13.2.3 Running the XSU Demo Programs
Demo programs for XSU are included in $ORACLE_HOME/xdk/demo/java/xsu.
Table 13-1 describes the XML files and programs that you can use to test XSU.
Table 13-1 XSU Sample Files
| File | Description |
|---|---|
|
|
A SQL script that sets up an object-relational schema and populates it. See XML Mapping Against an Object-Relational Schema. |
|
|
A SQL script that sets up an object-relational schema and populates it. See Altering the Database Schema or SQL Query. |
|
|
A SQL script that creates a relational table and then creates a customer view that contains a customer object on top of it. See Altering the Database Schema or SQL Query. |
|
|
An XML document that describes a customer. See Altering the Database Schema or SQL Query. |
|
|
A program that generates a DOM tree and then traverses it in document order, printing the nodes one by one. See Generating a DOM Tree with OracleXMLQuery. |
|
|
A README that describes the programs in the demo directory. |
|
|
A SQL script that queries the |
|
|
An XML document that describes a new employee. See Running the testInsert Program. |
|
|
An XML document that describes a new employee. See Running the testInsertSubset Program. |
|
|
A program that throws an exception when there are no more rows. See Raising a No Rows Exception. |
|
|
A program that uses the JDBC |
|
|
A program that generates an XML page that paginates results. See Paginating Results with OracleXMLQuery: Example. |
|
|
A program that generates XML from the results of the SQL query defined in the |
|
|
A program that queries the |
|
|
A program that inserts |
|
|
A program that queries the |
|
|
A sample XML data document that |
|
|
A SQL script that creates the |
|
|
A program that limits the number of elements used to identify a row, which improves performance by caching the |
|
|
A program that accepts an XML document file name as input and deletes the rows corresponding to the elements in the document. See Deleting by Row with OracleXMLSave. |
|
|
A sample program shown that throws a runtime exception and then gets the parent exception by invoking |
|
|
A Java program that inserts XML values into all columns of the |
|
|
A program shown that inserts XML data into a subset of columns. See Inserting XML into a Subset of Columns with OracleXMLSave. |
|
|
A PL/SQL script that creates a function that defines a REF cursor and returns it. Every time the |
|
|
A sample program that updates the |
|
|
Suppose you want to update only the salary and job title for each employee and ignore the other information. If you know that all the elements to be updated are the same for all |
|
|
A sample program that uses XSU to generate XML as a |
|
|
An XML document that contains updated salary and other information for a series of employees. See Running the testUpdate Program. |
|
|
An XML document that contains updated salary and other information for a series of employees. See Running the testUpdate Program. |
|
|
An XML document that contains new data for two employees. See Running the testUpdateList Program. |
The steps for running the demos are:
These sections describe the XSU demos in detail.
13.2.4 Using the XSU Command-Line Utility
XDK includes a command-line Java interface for XSU. XSU command-line options are provided through the Java class OracleXML.
To use this API ensure that your Java classpath is set as described in Setting Up the XDK for Java Environment.
To print usage information for XSU to standard output, run this command:
java OracleXML
To use XSU, invoke it with either the getXML or putXML parameter:
java OracleXML getXMLoptionsjava OracleXML putXMLoptions
Table 13-2 describes the getXML options.
Table 13-2 getXML Options
| getXML Option | Description |
|---|---|
|
|
Specifies the user name and password to connect to the database. The connect string is also specified. You can specify the user name and password as part of the connect string. |
|
|
Specifies the JDBC database connect string. By default the connect string is: " |
|
|
Instructs the XSU to generate the DTD along with the XML document. |
|
|
Instructs the XSU to generate the schema along with the XML document. |
|
|
Specifies the rowset tag, which is tag that encloses all the XML elements corresponding to the records returned by the query. The default rowset tag is |
|
|
Specifies the row tag that encloses the data corresponding to a database row. The default row tag is |
|
|
Names the attribute of the |
|
- |
Specifies that the value of a scalar column from the query is to be used as the value of the |
|
|
Names the attribute of an XML list element that keeps track of the cardinality of the elements of the list. The generated XML lists correspond to either a cursor query, or collection. If you specify an empty string ("") as the |
|
|
Specifies the use type name for the column-element tag. By default XSU uses the |
|
|
Specifies the attribute |
|
|
Specifies the stylesheet in the XML processing instruction. |
|
|
Specifies the stylesheet type in the XML processing instruction. |
|
|
Specifies the XSLT stylesheet to apply to the XML document. |
|
|
Sets the XSLT external entity reference. |
|
|
Generates lowercase or uppercase tag names. The default is to match the case of the SQL object names from which the tags are generated. |
|
|
Specifies the treatment of characters that are legal in SQL object names but illegal in XML tags. If such a character is encountered, then it is escaped so that it does not throw an exception. |
|
|
Specifies the tag to enclose error messages that are formatted as XML. |
|
|
Specifies that XSU must throw a Java exception. By default XSU catches any error and produces the XML error. |
|
|
Raises an exception if no rows are returned. |
|
|
Performs strict checking on input data. |
|
|
Specifies the maximum number of rows to be retrieved and converted to XML. |
|
|
Specifies the number of rows to be skipped. |
|
|
Specifies the character set encoding of the generated XML. |
|
|
Specifies the date format for the date values in the XML document. |
|
|
Specifies the file name that contains the query or the query itself. |
Table 13-3 describes the putXML options.
Table 13-3 putXML Options
| putXML Options | Description |
|---|---|
|
|
Specifies the user name and password to connect to the database. The connect string is also specified. You can specify the user name and password as part of the connect string. |
|
|
Specifies the JDBC database connect string. By default the connect string is: " |
|
|
Specifies the batch size that controls the number of rows that are batched together and inserted in a single trip to the database to improve performance. |
|
|
Specifies the number of inserted records after which a commit is to be executed. If the autocommit is |
|
|
Specifies the |
|
|
Specifies the date format for the date values in the XML document. |
|
|
Turns on reverse mapping if SQL to XML name escaping was used when generating the doc. |
|
|
Makes the matching of the column names with tag names case insensitive. For example, |
|
|
Preserves the white space in the inserted XML document. |
|
|
Specifies the XSLT to apply to the XML document before inserting. |
|
|
Sets the XSLT external entity reference. |
|
|
Specifies the XML document to insert: a local file, a URL, or an XML document as a string on the command line. |
|
|
Specifies the name of the table to put the values into. |
Topics:
- Generating XML with the XSU Command-Line Utility
To generate XML from the database schema use thegetXMLparameter. - Generating XMLType Data with the XSU Command-Line Utility
You can use XSU to generate XML from tables withXMLTypecolumns. - Performing DML with the XSU Command-Line Utility
An example shows how to insert an XML document into a database table.
13.2.4.1 Generating XML with the XSU Command-Line Utility
To generate XML from the database schema use the getXML parameter.
For example, to generate an XML document by querying the employees table in the hr schema, you can use this syntax:
java OracleXML getXML -user "hr/password" "SELECT * FROM employees"
The preceding command performs these tasks:
- Connects to the current default database
- Executes the specified
SELECTquery - Converts the SQL result set to XML
- Prints the XML to standard output
The getXML parameter supports a wide range of options, which are explained in Table 13-2.
13.2.4.2 Generating XMLType Data with the XSU Command-Line Utility
You can use XSU to generate XML from tables with XMLType columns.
Suppose that you run the demo script setup_xmltype.sql to create and populate the parts table. You can generate XML from this table with XSU:
java OracleXML getXML -user "hr/password" -rowTag "Part" "SELECT * FROM parts"
The output of the command is shown below:
<?xml version = '1.0'?>
<ROWSET>
<Part num="1">
<PARTNO>1735</PARTNO>
<PARTNAME>Gizmo</PARTNAME>
<PARTDESC>
<Description>
<Title>Description of the Gizmo</Title>
<Author>John Smith</Author>
<Body>
The <b>Gizmo</b> is <i>grand</i>.
</Body>
</Description>
</PARTDESC>
</Part>
</ROWSET>13.2.4.3 Performing DML with the XSU Command-Line Utility
An example shows how to insert an XML document into a database table.
To insert an XML document called new_employees.xml into the hr.employees table, use this syntax:
java OracleXML putXML -user "hr/password" -fileName "new_employees.xml" employees
The preceding command performs these tasks:
- Connects to the current database as
hr - Reads the XML document named
new_emp.xml - Parses the XML document, matching the tags with column names
- Inserts the values appropriately into the
employeestable
The getXML parameter supports a wide range of options, which are explained in Table 13-2.
13.3 Programming with the XSU Java API
Topics here include using OracleXMLQuery and OracleXMLSave to perform various operations, and handling XSU Java exceptions.
Topics:
- Generating a String with OracleXMLQuery
ThetestXMLSQL.javademo program uses XSU to generate XML as aStringobject. The program queries tablehr.employeesand prints the result set to standard output. - Generating a DOM Tree with OracleXMLQuery
To generate a DOM tree from the XML generated by XSU, you can directly request a DOM document from XSU. This technique saves the overhead of creating a string representation of the XML document and then parsing it to generate the DOM tree. - Paginating Results with OracleXMLQuery
Topics here include limiting the rows in a result set, keeping an object open during a user session, and paginating results usingOracleXMLQuery. - Generating Scrollable Result Sets
You might want to perform a query and then retrieve a previous page of results from within the result set. To enable scrolling, instantiate theOracle.jdbc.ResultSetclass. You can use theResultSetobject to move back and forth within the result set and use XSU to generate XML each time. - Generating XML from Cursor Objects
You can initialize aCallableStatementobject, execute a PL/SQL function that returns a cursor variable, get theOracleResultSetobject, and send it to anOracleXMLQueryobject to obtain the desired XML data. - Inserting Rows with OracleXMLSave
To insert a document into a table or view, supply the table or view name and the document. XSU parses the document and creates anINSERTstatement into which it binds the values. By default, XSU inserts values into all columns of the table or view. - Updating Rows Using OracleXMLSave
Examples show how to update the fields in a table or view. You supply the table or view name and an XML document. XSU parses the document (if a string is given) and creates one or moreUPDATEstatements into which it binds all of the values. - Deleting Rows using XSU
When deleting from XML documents, you can specify a list of key columns. XSU uses these columns in theWHEREclause of theDELETEstatement. If you do not supply the key column names, then XSU creates a newDELETEstatement for eachROWelement of the XML document. - Handling XSU Java Exceptions
XSU catches all exceptions that occur during processing and throwsoracle.xml.sql.OracleXMLSQLException, which is a generic runtime exception. The invoking program need not catch this exception if it can still perform the appropriate action. The exception class provides methods to get error messages and any parent exceptions.
13.3.1 Generating a String with OracleXMLQuery
The testXMLSQL.java demo program uses XSU to generate XML as a String object. The program queries table hr.employees and prints the result set to standard output.
The testXMLSQL.java program follows these steps:
Topics:
- Running the testXMLSQL Program
ThetestXMLSQLprogram is described.
13.3.1.1 Running the testXMLSQL Program
The testXMLSQL program is described.
To run the testXMLSQL.java program perform these steps:
- Compile
testXMLSQL.javawithjavac. - Execute
java testXMLSQLon the command line.
You must have the CLASSPATH pointing to this directory for the Java executable to find the class. Alternatively, use visual Java tools such as Oracle JDeveloper to compile and run this program. When run, this program prints out the XML file to the screen. This code shows sample output with some rows edited out:
<?xml version = '1.0'?>
<ROWSET>
<ROW num="1">
<EMPLOYEE_ID>100</EMPLOYEE_ID>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>King</LAST_NAME>
<EMAIL>SKING</EMAIL>
<PHONE_NUMBER>515.123.4567</PHONE_NUMBER>
<HIRE_DATE>6/17/1987 0:0:0</HIRE_DATE>
<JOB_ID>AD_PRES</JOB_ID>
<SALARY>24000</SALARY>
<DEPARTMENT_ID>90</DEPARTMENT_ID>
</ROW>
<!-- ROW num="2" through num="107" ... -->
</ROWSET>13.3.2 Generating a DOM Tree with OracleXMLQuery
To generate a DOM tree from the XML generated by XSU, you can directly request a DOM document from XSU. This technique saves the overhead of creating a string representation of the XML document and then parsing it to generate the DOM tree.
XSU invokes the Oracle XML parser to construct the DOM tree from the data values. The domTest.java demo program generates a DOM tree and then traverses it in document order, printing the nodes one by one.
The first two steps in the domTest.java program are the same as in the testXMLSQL.java program described in Generating a String with OracleXMLQuery. The program proceeds as follows:
After compiling the program, run it from the command line:
java domTest
13.3.3 Paginating Results with OracleXMLQuery
Topics here include limiting the rows in a result set, keeping an object open during a user session, and paginating results using OracleXMLQuery.
Topics:
- Limiting the Number of Rows in the Result Set
Different ways to limit the number of rows in a result set are described. - Keeping an Object Open for the Duration of the User's Session
In some situations, you might want to keep a query object open for the duration of the user session. You can handle such cases with themaxRows()method and thekeepObjectOpen()method. - Paginating Results with OracleXMLQuery: Example
ThepaginateResults.javaprogram shows how you can generate an XML page that paginates results. The output XML displays only 20 rows of thehrtable.
13.3.3.1 Limiting the Number of Rows in the Result Set
Different ways to limit the number of rows in a result set are described.
In testXMLSQL.java and domTest.java, XSU generated XML from all rows returned by the query. Suppose that you query a table that contains 1000 rows, but you want only 100 rows at a time. One approach is to execute one query to get the first 100 rows, another to get the next 100 rows, and so on. With this technique you cannot skip the first five rows of the query and then generate the result. To avoid these problems, use these Java methods:
-
OracleXMLSave.setSkipRows()forces XSU to skip the desired number of rows before starting to generate the result. The command-line equivalent to this method is the-skipRowsparameter. -
OracleXMLSave.setMaxRows()limits the number of rows converted to XML. The command-line equivalent to this method is the-maxRowsparameter.
Example 13-1 sets skipRows to a value of 5 and maxRows to a value of 1, which causes XSU to skip the first 5 rows and then generate XML for the next row when querying the hr.employees table.
The following shows sample output (only row 6 of the query result set is returned):
<?xml version = '1.0'?>
<ROWSET>
<ROW num="6">
<EMPLOYEE_ID>105</EMPLOYEE_ID>
<FIRST_NAME>David</FIRST_NAME>
<LAST_NAME>Austin</LAST_NAME>
<EMAIL>DAUSTIN</EMAIL>
<PHONE_NUMBER>590.423.4569</PHONE_NUMBER>
<HIRE_DATE>6/25/1997 0:0:0</HIRE_DATE>
<JOB_ID>IT_PROG</JOB_ID>
<SALARY>4800</SALARY>
<MANAGER_ID>103</MANAGER_ID>
<DEPARTMENT_ID>60</DEPARTMENT_ID>
</ROW>
</ROWSET>Example 13-1 Specifying skipRows and maxRows on the Command Line
java OracleXML getXML -user "hr/password" -skipRows 5 -maxRows 1 \
"SELECT * FROM employees"
13.3.3.2 Keeping an Object Open for the Duration of the User's Session
In some situations, you might want to keep a query object open for the duration of the user session. You can handle such cases with the maxRows() method and the keepObjectOpen() method.
Consider a web search engine that paginates search results. The first page lists 10 results, the next page lists 10 more, and so on. To perform this task with XSU, request 10 rows at a time and keep the ResultSet open so that the next time you ask XSU for more results, it starts generating from where the last generation finished. If OracleXMLQuery creates a result set from the SQL query string, then it typically closes the ResultSet internally because it assumes no more results are required. Thus, you must invoke keepObjectOpen() to keep the cursor active.
A different case requiring an open query object is when the number of rows or number of columns in a row is very large. In this case, you can generate multiple small documents rather than one large document.
Related Topics
13.3.3.3 Paginating Results with OracleXMLQuery: Example
The paginateResults.java program shows how you can generate an XML page that paginates results. The output XML displays only 20 rows of the hr table.
The paginateResults.java program shows how you can generate an XML page that paginates results. The output XML displays only 20 rows of the hr table.
The first step of the paginateResults.java program, which creates the connection, is the same as in testXMLSQL.java. The program continues as follows:
After compiling the program, run it from the command line:
java paginateResults
13.3.4 Generating Scrollable Result Sets
You might want to perform a query and then retrieve a previous page of results from within the result set. To enable scrolling, instantiate the Oracle.jdbc.ResultSet class. You can use the ResultSet object to move back and forth within the result set and use XSU to generate XML each time.
The pageTest.java program shows how to use the JDBC ResultSet to generate XML a page at a time. Using ResultSet may be necessary in cases that are not handled directly by XSU, for example, when setting the batch size and binding values.
The pageTest.java program creates a pageTest object and initializes it with a SQL query. The constructor for the pageTest object performs these steps:
After compiling the program, run it from the command line:
java pageTest
13.3.5 Generating XML from Cursor Objects
You can initialize a CallableStatement object, execute a PL/SQL function that returns a cursor variable, get the OracleResultSet object, and send it to an OracleXMLQuery object to obtain the desired XML data.
Class OracleXMLQuery provides XML conversion only for query strings or ResultSet objects. If your program uses PL/SQL procedures that return REF cursors, then how do you perform the conversion? You can use the ResultSet conversion mechanism described in Generating Scrollable Result Sets.
REF cursors are references to cursor objects in PL/SQL. These cursor objects are SQL statements over which a program can iterate to get a set of values. The cursor objects are converted into OracleResultSet objects in the Java world. In your Java program you can initialize a CallableStatement object, execute a PL/SQL function that returns a cursor variable, get the OracleResultSet object, and then send it to the OracleXMLQuery object to get the desired XML.
Consider the testRef PL/SQL package defined in the testRef.sql script. It creates a function that defines a REF cursor and returns it. Every time the testRefCur PL/SQL function is called, it opens a cursor object for the SELECT query and returns that cursor instance. To convert the object to XML, do this:
- Run the
testRef.sqlscript to create thetestRefpackage in thehrschema. - Compile and run the
refCurTest.javaprogram to generate XML from the results of the SQL query defined in thetestRefCurfunction.
To apply the stylesheet, you can use the applyStylesheet command, which forces the stylesheet to be applied before generating the output.
13.3.6 Inserting Rows with OracleXMLSave
To insert a document into a table or view, supply the table or view name and the document. XSU parses the document and creates an INSERT statement into which it binds the values. By default, XSU inserts values into all columns of the table or view.
An absent element is treated as a NULL value. The following example shows how you can store the XML document generated from the hr.employees table in the table.
Topics:
- Inserting XML into All Columns with OracleXMLSave
ThetestInsert.javademo program inserts XML values into all columns of thehr.employeestable. - Inserting XML into a Subset of Columns with OracleXMLSave
In some situations, you might not want to insert values into all columns. For example, the group of values that you get might not be the complete set, requiring you to use triggers or default values for the remaining columns.
13.3.6.1 Inserting XML into All Columns with OracleXMLSave
The testInsert.java demo program inserts XML values into all columns of the hr.employees table.
The program follows these steps:
Topics:
- Running the testInsert Program
ThetextInsertprogram is described.
13.3.6.1.1 Running the testInsert Program
The textInsert program is described.
Assume that you write the new_emp.xml document to describe new employee Janet Smith, who has employee ID 7369. You pass the file name new_emp.xml as an argument to the testInsert program:
java testInsert "new_emp.xml"
The program inserts a new row in the employees table that contains the values for the columns specified. Any absent element inside the row element is treated as NULL.
Running the program generates an INSERT statement of this form:
INSERT INTO hr.employees (employee_id, first_name, last_name, email, phone_number, hire_date, salary, commission_pct, manager_id, department_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
XSU matches the element tags in the input XML document that match the column names and binds their values.
13.3.6.2 Inserting XML into a Subset of Columns with OracleXMLSave
In some situations, you might not want to insert values into all columns. For example, the group of values that you get might not be the complete set, requiring you to use triggers or default values for the remaining columns.
The testInsertSubset.java demo program shows how to handle this case. It follows these steps:
Topics:
- Running the testInsertSubset Program
ThetestInsertSubsetprogram is described.
13.3.6.2.1 Running the testInsertSubset Program
The testInsertSubset program is described.
Assume that you use the new_emp2.xml document to store data for new employee Adams, who has employee ID 7400. You pass new_emp2.xml as an argument to the testInsert program:
java testInsert new_emp2.xml
The program ignores values for the columns that were not specified in the input file. It performs an INSERT for each ROW element in the input and batches the INSERT statements by default.
The program generates this INSERT statement:
INSERT INTO hr.employees (employee_id, last_name, email, job_id, hire_date) VALUES (?, ?, ?, ?, ?);
13.3.7 Updating Rows Using OracleXMLSave
Examples show how to update the fields in a table or view. You supply the table or view name and an XML document. XSU parses the document (if a string is given) and creates one or more UPDATE statements into which it binds all of the values.
The following examples use an XML document to update table hr.employees.
Topics:
- Updating Key Columns Using OracleXMLSave
Demo programtestUpdate.javainvokes methodOracleXMLSave.setKeyColumnList()to update tablehr.employees. - Updating a Column List Using OracleXMLSave
13.3.7.1 Updating Key Columns Using OracleXMLSave
Demo program testUpdate.java invokes method OracleXMLSave.setKeyColumnList() to update table hr.employees.
testUpdate.java follows these steps:
Topics:
- Running the testUpdate Program
ThetestUpdateprogram is described.
13.3.7.1.1 Running the testUpdate Program
The testUpdate program is described.
You can use XSU to update specified fields in a table. Example 13-2 shows upd_emp.xml, which contains updated salary and other information for the two employees that you just added, 7369 and 7400.
For updates, supply XSU with the list of key column names in the WHERE clause of the UPDATE statement. In the hr.employees table the employee_id column is the key.
Pass the file name upd_emp.xml as an argument to the preceding program:
java testUpdate upd_emp.xml
The program generates two UPDATE statements. For the first ROW element, the program generates an UPDATE statement to update the SALARY field:
UPDATE hr.employees SET salary = 3250 WHERE employee_id = 7400;
For the second ROW element the program generates this statement:
UPDATE hr.employees SET job_id = 'SA_REP' AND MANAGER_ID = 145 WHERE employee_id = 7369;
Example 13-2 upd_emp.xml
<?xml version='1.0'?>
<ROWSET>
<ROW num="1">
<EMPLOYEE_ID>7400</EMPLOYEE_ID>
<SALARY>3250</SALARY>
</ROW>
<ROW num="2">
<EMPLOYEE_ID>7369</EMPLOYEE_ID>
<JOB_ID>SA_REP</JOB_ID>
<MANAGER_ID>145</MANAGER_ID>
</ROW>
<!-- additional rows ... -->
</ROWSET>
13.3.7.2 Updating a Column List Using OracleXMLSave
You can update a table using only a subset of the elements in an XML document, by specifying a list of columns. This is fast because XSU uses the same UPDATE statement, with bind variables for all of the ROW elements. Other tags in the document can be ignored.
Note:
When you specify a list of columns to update, if an element corresponding to an update column is absent, XSU treats it as NULL.
Suppose you want to update the salary and job title for each employee and ignore the other data. If you know that all the elements to be updated are the same for all ROW elements in the XML document, then you can use the OracleXMLSave.setUpdateColumnNames() method to specify the columns. The testUpdateList.java program shows this technique.
The testUpdateList.java program follows these steps:
Topics:
- Running the testUpdateList Program
ThetestUpdateListprogram is described.
13.3.7.2.1 Running the testUpdateList Program
The testUpdateList program is described.
Suppose that you use the sample XML document upd_emp2.xml to store new data for employees Steven King, who has an employee ID of 100, and William Gietz, who has an employee identifier (ID) of 206. You pass upd_emp2.xml as an argument to the testUpdateList program:
java testUpdateList upd_emp2.xml
In this example, the program generates two UPDATE statements. For the first ROW element, the program generates this statement:
UPDATE hr.employees SET salary = 8350 AND job_id = 'AC_ACCOUNT' WHERE employee_id = 100;
For the second ROW element the program generates this statement:
UPDATE hr.employees SET salary = 25000 AND job_id = 'AD_PRES' WHERE employee_id = 206;
13.3.8 Deleting Rows using XSU
When deleting from XML documents, you can specify a list of key columns. XSU uses these columns in the WHERE clause of the DELETE statement. If you do not supply the key column names, then XSU creates a new DELETE statement for each ROW element of the XML document.
The list of columns in the WHERE clause of the DELETE statement matches those in the ROW element.
Topics:
- Deleting by Row with OracleXMLSave
ThetestDeleteRow.javademo program accepts an XML document file name as input and deletes the rows corresponding to the elements in the document. - Deleting by Key with OracleXMLSave
To use only the key values as predicates on theDELETEstatement, invoke theOracleXMLSave.setKeyColumnList()method. This approach limits the number of elements used to identify a row, which has the benefit of improving performance by caching theDELETEstatement and batching transactions. ThetestDeleteKey.javaprogram shows this technique.
13.3.8.1 Deleting by Row with OracleXMLSave
The testDeleteRow.java demo program accepts an XML document file name as input and deletes the rows corresponding to the elements in the document.
The testDeleteRow.java program follows these steps:
Topics:
- Running the testDelete Program
ThetestDeleteprogram is described.
13.3.8.1.1 Running the testDelete Program
The testDelete program is described.
This section shows how to delete the employees 7400 and 7369 that you added in Inserting Rows with OracleXMLSave.
To make this example work correctly, connect to the database and disable a constraint on the hr.job_history table:
CONNECT hr ALTER TABLE job_history DISABLE CONSTRAINT JHIST_EMP_FK; EXIT
Now pass upd_emp.xml to the testDeleteRow program:
java testDeleteRow upd_emp.xml
The program forms the DELETE statements based on the tag names present in each ROW element in the XML document. It executes these statements:
DELETE FROM hr.employees WHERE salary = 3250 AND employee_id = 7400; DELETE FROM hr.employees WHERE job_id = 'SA_REP' AND MANAGER_ID = 145 AND employee_id = 7369;
13.3.8.2 Deleting by Key with OracleXMLSave
To use only the key values as predicates on the DELETE statement, invoke the OracleXMLSave.setKeyColumnList() method. This approach limits the number of elements used to identify a row, which has the benefit of improving performance by caching the DELETE statement and batching transactions. The testDeleteKey.java program shows this technique.
The testDeleteKey.java program follows these steps:
Topics:
- Running the testDeleteKey Program
ThetestDeleteKeyprogram is described.
13.3.8.2.1 Running the testDeleteKey Program
The testDeleteKey program is described.
This section shows how to delete employees 7400 and 7369 that you added in Updating Key Columns Using OracleXMLSave. If you deleted these employees in the previous example, you can add them back to the employees table:
java testInsert new_emp.xml java testInsert new_emp2.xml
Delete employees 7400 and 7369 by passing the same upd_emp.xml document to the testDeleteRow program:
java testDeleteKey upd_emp.xml
The program forms this single generated DELETE statement:
DELETE FROM hr.employees WHERE employee_id=?;
The program executes these DELETE statements, one for each employee:
DELETE FROM hr.employees WHERE employee_id = 7400; DELETE FROM hr.employees WHERE employee_id = 7369;
13.3.9 Handling XSU Java Exceptions
XSU catches all exceptions that occur during processing and throws oracle.xml.sql.OracleXMLSQLException, which is a generic runtime exception. The invoking program need not catch this exception if it can still perform the appropriate action. The exception class provides methods to get error messages and any parent exceptions.
Topics:
- Getting the Parent Exception
ThetestException.javademo program throws a runtime exception and then gets the parent exception by invokingException.getParentException(). - Raising a No Rows Exception
When there are no rows to process, XSU returns anullstring. You can throw an exception each time there are no more rows, however, so that a program can process this exception using exception handlers.
13.3.9.1 Getting the Parent Exception
The testException.java demo program throws a runtime exception and then gets the parent exception by invoking Exception.getParentException().
Running the program generates this error message:
Caught SQL Exception:ORA-00904: "SD": invalid identifier
13.3.9.2 Raising a No Rows Exception
When there are no rows to process, XSU returns a null string. You can throw an exception each time there are no more rows, however, so that a program can process this exception using exception handlers.
When a program invokes OracleXMLQuery.setRaiseNoRowsException(), XSU raises an oracle.xml.sql.OracleXMLSQLNoRowsException whenever there are no rows to generate for the output. This is a runtime exception and need not be caught.
The noRowsTest.java demo program instantiates the pageTest class defined in pageTest.java. The condition to check the termination changed from checking whether the result is null to an exception handler.
The noRowsTest.java program creates a pageTest object and initializes it with a SQL query. The program proceeds as follows:
After compiling the program, run it from the command line:
java noRowsTest
13.4 Programming with the XSU PL/SQL API
Topics here describe programming tasks that make use of the XSU PL/SQL API.
Note:
For increased performance, consider using DBMS_XMLGen and DBMS_XMLStore as alternatives to DBMS_XMLQuery and DBMS_XMLSave. The two former packages are written in C and are built in to the database kernel. You can also use SQL and XML functions such as XMLElement for XML access in the database.
Topics:
- Generating XML from Simple Queries with DBMS_XMLQuery
How you can use packageDBMS_XMLQueryto generate XML data from a SQL query is shown. - Specifying Element Names with DBMS_XMLQuery
With the XSU PL/SQL API you can change the defaultROWand theROWSETelement names, which are the default names placed around each row of the result and around the whole output XML document. Use PL/SQL proceduressetRowTagNameandsetRowSetTagNameto accomplish this task. - Paginating Results with DBMS_XMLQUERY
You can paginate query results by invoking functions in PL/SQL packageDBMS_XMLQUERY. - Setting Stylesheets in XSU
The XSU PL/SQL API lets you set stylesheets on generated XML documents. - Binding Values in XSU
The XSU PL/SQL API lets you bind values to a SQL statement. The statement can contain named bind variables, which must be prefixed with a colon (:). - Inserting XML using XSU
To insert a document into a table or view, supply the table or the view name and then the XML document. XSU parses the XML document (if a string is given) and then creates anINSERTstatement into which it binds all the values. By default, XSU inserts values into all the columns of the table or view and treats absent elements asNULL. - Updating using XSU
You can use an XML document to update specified fields in a table. You can either specify a column to use as a key or pass a list of columns for updating. - Deleting with XSU
you can supply a list of key columns that XSU uses to determine which rows to delete. XSU specifies these columns in theWHEREclause of theDELETEstatement. - Handling Exceptions with XSU
A sample script shows how to handle exceptions using XSU. - Reusing the Context Handle with XSU
You can sometimes perform more than one operation using the same context handle.
13.4.1 Generating XML from Simple Queries with DBMS_XMLQuery
How you can use package DBMS_XMLQuery to generate XML data from a SQL query is shown.
To make the example work, connect to the database as hr and run the printClobOut.sql script. The script creates printClobOut, which is a simple procedure that prints a CLOB to the output buffer. If you run the printClobOut procedure in SQL*Plus, it prints the input CLOB to the screen. Set server output to ON to see the results. You might have to increase your display buffer to see all the output.
Run the simpleQuery.sql script to select 20 rows from the hr.employees table and get an XML document as a CLOB. The program first gets the context handle by passing in a query and then invokes the getXML function to get the CLOB value. The document is in the same encoding as the database character set. This sample application assumes that you created the printClobOut procedure by running printClobOut.sql.
13.4.2 Specifying Element Names with DBMS_XMLQuery
With the XSU PL/SQL API you can change the default ROW and the ROWSET element names, which are the default names placed around each row of the result and around the whole output XML document. Use PL/SQL procedures setRowTagName and setRowSetTagName to accomplish this task.
Connect as hr and run the changeElementName.sql script in SQL*Plus to get the first 20 rows of the employees table as an XML document. The anonymous PL/SQL block changes the ROW and ROWSET element names to EMP and EMPSET. The block invokes the printClobOut procedure that you created by running printClobOut.sql.
The generated XML document has an <EMPSET> document element. Each row is separated with the <EMP> tag.
13.4.3 Paginating Results with DBMS_XMLQUERY
You can paginate query results by invoking functions in PL/SQL package DBMS_XMLQUERY.
-
Function
setMaxRowssets the maximum number of rows to be converted to XML. This maximum is relative to the current row position from which the previous result was generated. -
Function
setSkipRowsspecifies the number of rows to skip before converting the row values to XML.
Run the paginateResult.sql script to execute an anonymous block that paginates results. It skips the first 3 rows of the employees table and prints the rest of the rows 10 at a time by setting skipRows to 3 for the first batch of 10 rows and then to 0 for the rest of the batches. For multiple fetches, you must determine when there are no more rows to fetch, which you can do by invoking setRaiseNoRowsException. This procedure raises an exception if no rows are written to the CLOB. This exception can be caught and used as the termination condition.
13.4.4 Setting Stylesheets in XSU
The XSU PL/SQL API lets you set stylesheets on generated XML documents.
-
Set the stylesheet header in the result with procedure
setStylesheetHeader. This procedure adds the XML processing instruction that includes the stylesheet. -
Apply a stylesheet to the resulting XML document before generation. This method increases performance dramatically because otherwise the XML document must be generated as a
CLOB, sent to the parser again, and have the stylesheet applied. XSU generates a DOM document, invokes the parser, applies the stylesheet and then generates the result. To apply the stylesheet to the resulting XML document, use proceduresetXSLT, which uses the stylesheet to generate the result.
13.4.5 Binding Values in XSU
The XSU PL/SQL API lets you bind values to a SQL statement. The statement can contain named bind variables, which must be prefixed with a colon (:).
The bindSQLVariables.sql script runs an anonymous PL/SQL block that binds values for EMPLOYEE_ID and FIRST_NAME to columns in the employees table.
13.4.6 Inserting XML using XSU
To insert a document into a table or view, supply the table or the view name and then the XML document. XSU parses the XML document (if a string is given) and then creates an INSERT statement into which it binds all the values. By default, XSU inserts values into all the columns of the table or view and treats absent elements as NULL.
Topics:
- Inserting Values into All Columns using XSU
Run theinsProc.sqldemo script to create a PL/SQL stored procedure,insProc. - Inserting into a Set of Columns using XSU
You can create a list of column names for insert processing and pass it to PL/SQL procedureDBMS_XMLSave.
13.4.6.1 Inserting Values into All Columns using XSU
Run the insProc.sql demo script to create a PL/SQL stored procedure, insProc.
The script accepts these parameters:
-
An XML document as a
CLOB -
The name of the table in which to insert the document
You can invoke the insProc procedure to insert an XML document into the table.
Run the insertClob.sql script to create a table called xmldocument and store an XML document in the table as a CLOB. The XML document describes employee 7370, Liz Gardner, whom you want to insert into the hr.employees table.
Run the insertEmployee.sql script shown in Example 13-4 to call the insProc stored procedure and insert Liz Gardner into the employees table.
As in Inserting Rows with OracleXMLSave, running the callinsProc procedure generates an INSERT statement of the form shown in Example 13-5.
XSU matches the element tags in the input XML document that match the column names and binds their values.
Example 13-3 insertClob.sql
CREATE TABLE hr.xmldocument
(docid NUMBER PRIMARY KEY,
xml_text CLOB);
-- insert an XML document into the CLOB column
INSERT INTO hr.xmldocument (docid,xml_text)
VALUES (1,
'<?xml version="1.0"?>
<ROWSET>
<ROW num="1">
<EMPLOYEE_ID>7370</EMPLOYEE_ID>
<FIRST_NAME>Liz</FIRST_NAME>
<LAST_NAME>Gardner</LAST_NAME>
<EMAIL>liz.gardner@business.com</EMAIL>
<PHONE_NUMBER>650-555-6127</PHONE_NUMBER>
<HIRE_DATE>12/18/2004 0:0:0</HIRE_DATE>
<SALARY>3000</SALARY>
<COMMISSION_PCT>0</COMMISSION_PCT>
<JOB_ID>SH_CLERK</JOB_ID>
<MANAGER_ID>103</MANAGER_ID>
<DEPARTMENT_ID>20</DEPARTMENT_ID>
</ROW>
</ROWSET>');
Example 13-4 insertEmployee.sql
DECLARE
v_xml_text CLOB;
BEGIN
SELECT xml_text
INTO v_xml_text
FROM hr.xmldocument
WHERE docid = 1;
insProc(v_xml_text, 'employees');
END;
/
Example 13-5 Form of the INSERT Statement
INSERT INTO hr.employees (employee_id, first_name, last_name, email, phone_number, hire_date, salary, commission_pct, manager_id, department_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
13.4.6.2 Inserting into a Set of Columns using XSU
You can create a list of column names for insert processing and pass it to PL/SQL procedure DBMS_XMLSave.
As explained in Inserting XML into a Subset of Columns with OracleXMLSave, you may not want to insert values into all columns. You can set these values by invoking procedure setUpdateColumnName repeatedly and passing in a column name to update each time. Clear the column name settings by invoking clearUpdateColumnList.
Run the testInsert.sql demo script to create a PL/SQL stored procedure called testInsert. You can use this procedure to insert XML data of type CLOB into the hr.employees table.
Run the insertClob2.sql script shown in Example 13-6 to insert an XML document describing new employee Jordan into a CLOB column of the xmldocument table. The document does not contain an element corresponding to every column in the employees table.
Running the insertEmployee2.sql script shown in Example 13-7 inserts the data for employee Jim Jordan into a subset of the columns in the hr.employees table.
As in Inserting XML into a Subset of Columns with OracleXMLSave, invoking testInsert generates this INSERT statement:
INSERT INTO hr.employees (employee_id, last_name, email, job_id, hire_date) VALUES (?, ?, ?, ?, ?);
Example 13-6 insertClob2.sql
-- insert an XML document into the CLOB column of the xmldocument table with only
-- some of the possible elements
INSERT INTO hr.xmldocument (docid, xml_text)
VALUES (2,
'<?xml version="1.0"?>
<ROWSET>
<ROW num="1">
<EMPLOYEE_ID>7401</EMPLOYEE_ID>
<LAST_NAME>Jordan</LAST_NAME>
<EMAIL>jim.jordan@business.com</EMAIL>
<JOB_ID>SH_CLERK</JOB_ID>
<HIRE_DATE>12/17/2004 0:0:0</HIRE_DATE>
</ROW>
</ROWSET>');
Example 13-7 insertEmployee2.sql
DECLARE
v_xml_text CLOB;
BEGIN
SELECT xml_text
INTO v_xml_text
FROM hr.xmldocument
WHERE docid = 2;
testInsert(v_xml_text);
END;
/
13.4.7 Updating using XSU
You can use an XML document to update specified fields in a table. You can either specify a column to use as a key or pass a list of columns for updating.
This is described in Updating Rows Using OracleXMLSave.
Topics:
- Updating Key Columns using PL/SQL
Example scripts show you how to update key columns using a PL/SQL procedure. - Updating a Set of Columns using XSU
You can specify a list of columns to update and pass it to PL/SQL procedureDBMS_XMLSave.
13.4.7.1 Updating Key Columns using PL/SQL
Example scripts show you how to update key columns using a PL/SQL procedure.
Run the testUpdateKey.sql script to create a PL/SQL procedure called testUpdateKey. The procedure uses column employee_id of the hr.employees table as a primary key.
Run the insertClob3.sql script shown in shown in Example 13-8 to insert an XML document into the CLOB column of table xmldocument. The document specifies a new salary for employee 7400 and a new job ID and manager ID for employee 7369.
Run the updateEmployee.sql script shown in Example 13-9 to pass the XML document to procedure testUpdateKey and generate two UPDATE statements.
For the first ROW element, the program generates an UPDATE statement:
UPDATE hr.employees SET salary = 3250 WHERE employee_id = 7400;
For the second ROW element the program generates this statement:
UPDATE hr.employees SET job_id = 'SA_REP' AND MANAGER_ID = 145 WHERE employee_id = 7369;
Example 13-8 insertClob3.sql
INSERT INTO hr.xmldocument (docid, xml_text)
VALUES (3,
'<?xml version="1.0"?>
<ROWSET>
<ROW num="1">
<EMPLOYEE_ID>7400</EMPLOYEE_ID>
<SALARY>3250</SALARY>
</ROW>
<ROW num="2">
<EMPLOYEE_ID>7369</EMPLOYEE_ID>
<JOB_ID>SA_REP</JOB_ID>
<MANAGER_ID>145</MANAGER_ID>
</ROW>
</ROWSET>');
Example 13-9 updateEmployee.sql
DECLARE
v_xml_text CLOB;
BEGIN
SELECT xml_text
INTO v_xml_text
FROM hr.xmldocument
WHERE docid = 3;
testUpdateKey(v_xml_text);
END;
/
13.4.7.2 Updating a Set of Columns using XSU
You can specify a list of columns to update and pass it to PL/SQL procedure DBMS_XMLSave.
This is described in Updating a Column List Using OracleXMLSave.
Run the testUpdateSubset.sql script creates the PL/SQL procedure testUpdateSubset. The procedure uses column employee_id as key and updates only the salary and job_id columns of table hr.employees.
Run the insertClob4.sql script to insert an XML document into the xmldocument table. The <ROW> elements in the document describe employees 100 and 206. Each <ROW> element has ten subelements that contain descriptive text.
Run the updateEmployee2.sql script shown in Example 13-10 to pass the XML CLOB to procedure testUpdateSubset and generate two UPDATE statements.
The procedure updates only those columns specified in the setUpdateColumn procedure, salary and email, for employees 100 and 206.
Example 13-10 updateEmployee2.sql
DECLARE
v_xml_text CLOB;
BEGIN
SELECT xml_text
INTO v_xml_text
FROM hr.xmldocument
WHERE docid = 4;
testUpdateSubset(v_xml_text);
END;
/
13.4.8 Deleting with XSU
you can supply a list of key columns that XSU uses to determine which rows to delete. XSU specifies these columns in the WHERE clause of the DELETE statement.
This is described in Deleting Rows using XSU.
Topics:
- Deleting by Row with XSU
You can delete a row from a table using a PL/SQL procedure. - Deleting by Key with XSU
You can specify a column to use as a primary key for the deletions. Use PL/SQL functionDBMS_XMLSave.setKeyColumnto specify the key.
13.4.8.1 Deleting by Row with XSU
You can delete a row from a table using a PL/SQL procedure.
Create the testDeleteRow PL/SQL procedure by running the testDeleteRow.sql script. The procedure deletes a row from the hr.employees table for every <ROW> element in an input XML document.
Suppose you want to delete the employee Jim Jordan that you added in Example 13-7. Run the deleteEmployeeByRow.sql script shown in Example 13-11 to pass the XML document as a CLOB to the testDeleteRow stored procedure.
The preceding invocation of testDeleteRow generates this DELETE statement:
DELETE FROM hr.employees WHERE employee_id = 7401 AND last_name = 'JORDAN' AND email = 'jim.jordan@business.com' AND job_id = 'SH_CLERK' AND hire_date = '12/17/2004 0:0:0';
The program forms the DELETE statements based on the tag names present in each <ROW> element in the XML document.
Example 13-11 Deleting by Row
DECLARE
v_xml_text CLOB;
BEGIN
SELECT xml_text
INTO v_xml_text
FROM hr.xmldocument
WHERE docid = 2;
testDeleteRow(v_xml_text);
END;
/
13.4.8.2 Deleting by Key with XSU
You can specify a column to use as a primary key for the deletions. Use PL/SQL function DBMS_XMLSave.setKeyColumn to specify the key.
This is explained in Deleting by Key with OracleXMLSave.
Procedure testDeleteKey, created by running testDeleteKey.sql, deletes a row from table employees for each <ROW> element in an input XML document.
Suppose you want to delete the employee Liz Gardner that you added in Example 13-4. Run the deleteEmployeeByKey.sql script shown in Example 13-12 to pass the XML document as a CLOB to the testDeleteKey stored procedure.
In the procedure call, XSU generates a single DELETE statement of this form:
DELETE FROM hr.employees WHERE employee_id=?
XSU uses this statement for all ROW elements in the input XML document.
Example 13-12 Deleting by Key
DECLARE
v_xml_text CLOB;
BEGIN
SELECT xml_text
INTO v_xml_text
FROM hr.xmldocument
WHERE docid = 1;
testDeleteKey(v_xml_text);
END;
/
13.4.9 Handling Exceptions with XSU
A sample script shows how to handle exceptions using XSU.
Good PL/SQL coding practice accounts for possible exceptions. The anonymous PL/SQL block in raiseException.sql demonstrates how to invoke procedure DBMS_XMLQuery.getExceptionContent. Run the script in SQL*Plus to print this error message:
Exception caught 904 ORA-00904: "Z": invalid identifier
13.4.10 Reusing the Context Handle with XSU
You can sometimes perform more than one operation using the same context handle.
In the DML examples described in the preceding sections, you can use the same context handle to perform more than one operation. That is, you can perform more than one INSERT with the same context, if all of the insertions access the same table specified when creating the save context. You can also use the same context to mix DML statements.
The testDML.sql script shows how to use the same context and settings to perform DML depending on user input. The example uses a PL/SQL supplied package static variable to store the context so that the same context can be used for all function invocations.
In the testDML package created by the script, you create a context once for the whole package (and thus the session) and reuse the context for multiple DML operations.
Note:
The key column employee_id is used both for updates and deletes as a way of identifying the row.
You can call any of the three procedures created by the script to update the employees table:
testDML.insertXML(xmlclob); testDML.deleteXML(xmlclob); testDML.updateXML(xmlclob);
Each procedure call uses the same context, which improves the performance of these operations, particularly if these operations are performed frequently.
13.5 Tips and Techniques for Programming with XSU
This section provides tips and techniques for writing programs with XSU.
Topics:
- How XSU Maps Between SQL and XML
The mapping between SQL and XML is described. - How XSU Processes SQL Statements
How XSU processes SQL statements is described.
13.5.1 How XSU Maps Between SQL and XML
The mapping between SQL and XML is described.
The fundamental component of a table is a column, whereas the fundamental components of an XML document are elements and attributes. How do tables map to XML documents? For example, if the hr.employees table has a column called last_name, how is this structure represented in XML: as an <EMPLOYEES> element with a last_name attribute or as a <LAST_NAME> element within a different root element? This section answers such questions by describing how SQL maps to XML and the reverse.
Topics:
- Default SQL-to-XML Mapping
The default mapping of SQL data to XML data is described. - Default XML-to-SQL Mapping
The default mapping of XML data to SQL data is described. - Customizing Generated XML
In some situations, you might need to generate XML with a specific structure. Because the desired structure might differ from the default structure of the generated XML document, you need to have some flexibility in this process.
13.5.1.1 Default SQL-to-XML Mapping
The default mapping of SQL data to XML data is described.
To display data from some column of the hr.employees table as an XML document, run XSU at the command line:
java OracleXML getXML -user "hr/password" -withschema \
"SELECT employee_id, last_name, hire_date FROM employees"
XSU outputs an XML document based on the input query. The root element of the document is <DOCUMENT>. The following shows sample output, with extraneous lines replaced by comments:
<?xml version = '1.0'?>
<DOCUMENT xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- children of schema element ... -->
</xsd:schema>
<ROWSET xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="#/DOCUMENT/xsd:schema[not(@targetNamespace)]">
<ROW num="1">
<EMPLOYEE_ID>100</EMPLOYEE_ID>
<LAST_NAME>King</LAST_NAME>
<HIRE_DATE>6/17/1987 0:0:0</HIRE_DATE>
</ROW>
<!-- additional rows ... -->
</ROWSET>
</DOCUMENT>
In the generated XML, the rows returned by the SQL query are children of the <ROWSET> element. The XML document has these features:
-
The
<ROWSET>element has zero or more<ROW>child elements corresponding to the number of rows returned. If the query generates no rows, then no<ROW>elements are included; if the query generates one row, then one<ROW>element is included, and so forth. -
Each
<ROW>element contains data from one table row. Specifically, each<ROW>element has one or more child elements whose names and content are identical to the database columns specified in theSELECTstatement.
Topics:
- XML Mapping Against an Object-Relational Schema
XSU can generate an XML document from an object-relational schema. - Default Mapping of Complex Type Columns to XML
The default mapping of complex-type columns to XML data is described. - Default Mapping of Collections to XML
The default mapping of database collections to XML data is described.
13.5.1.1.1 XML Mapping Against an Object-Relational Schema
XSU can generate an XML document from an object-relational schema.
Run the createObjRelSchema.sql script in SQL*Plus to set up and populate an object-relational schema. The schema contains a dept1 table with two columns that employ user-defined types.
You can query the dept1 table by invoking XSU from the command line:
% java OracleXML getXML -user "hr/password" -withschema "SELECT * FROM dept1"
XSU returns the XML document shown in Example 13-13, which is altered so that extraneous lines are replaced by comments.
As in the previous example, the mapping is canonical, that is, <ROWSET> contains <ROW> child elements, which in turn contain child elements corresponding to the columns in dept1. For example, the <DEPTNAME> element corresponds to the dept1.deptname column. The elements corresponding to scalar type columns contain the data from the columns.
Example 13-13 XSU-Generated Sample Document
<?xml version='1.0'?>
<DOCUMENT xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<schema targetNamespace="http://xmlns.oracle.com/xdb/SYSTEM"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:SYSTEM="http://xmlns.oracle.com/xdb/SYSTEM">
<!-- children of schema element ... -->
</xsd:schema>
<ROWSET xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="#/DOCUMENT/xsd:schema[not(@targetNamespace)]">
<ROW num="1">
<DEPTNO>120</DEPTNO>
<DEPTNAME>Treasury</DEPTNAME>
<DEPTADDR>
<STREET>2004 Charade Rd</STREET>
<CITY>Seattle</CITY>
<STATE>WA</STATE>
<ZIP>98199</ZIP>
</DEPTADDR>
<EMPLIST>
<EMPLIST_ITEM>
<EMPLOYEE_ID>1</EMPLOYEE_ID>
<LAST_NAME>Mehta</LAST_NAME>
<SALARY>6000</SALARY>
<EMPLOYEE_ADDRESS>
<STREET>500 Main Road</STREET>
<CITY>Seattle</CITY>
<STATE>WA</STATE>
<ZIP>98199</ZIP>
</EMPLOYEE_ADDRESS>
</EMPLIST_ITEM>
</EMPLIST>
</ROW>
</ROWSET>
</DOCUMENT>
13.5.1.1.2 Default Mapping of Complex Type Columns to XML
The default mapping of complex-type columns to XML data is described.
The situation is more complex with elements corresponding to a complex-type column. In Example 13-13, <DEPTADDR> corresponds to the dept1.deptAddr column, which is of object type AddressType. Consequently, <DEPTADDR> contains child elements corresponding to the attributes specified in the type AddressType. The AddressType attribute street corresponds to the child XML element <STREET> and so forth. These subelements can contain data or subelements of their own, depending on whether the attribute they correspond to is of a simple or complex type.
13.5.1.1.3 Default Mapping of Collections to XML
The default mapping of database collections to XML data is described.
When dealing with elements corresponding to database collections, the situation is also different. In Example 13-13, the <EMPLIST> element corresponds to the emplist column of type EmployeeListType. Consequently, the <EMPLIST> element contains a list of <EMPLIST_ITEM> elements, each corresponding to an element of the collection. Note:
-
The
<ROW>elements contain a cardinality attributenum. -
If a particular column or attribute value is
NULL, then for that row, the corresponding XML element is omitted. -
If a top-level scalar column name starts with the at sign (
@) character, then the column is mapped to an XML attribute instead of an XML element.
13.5.1.2 Default XML-to-SQL Mapping
The default mapping of XML data to SQL data is described.
XML to SQL mapping is the reverse of SQL to XML mapping. Consider these differences when using XSU to map XML to SQL:
-
When transforming XML to SQL, XSU ignores XML attributes. Thus, there is really no mapping of XML attributes to SQL.
-
When transforming SQL to XML, XSU performs the mapping on a single
ResultSetcreated by a SQL query. The query can span multiple database tables or views. When transforming XML into SQL, note:-
To insert one XML document into multiple tables or views, you must create an object-relational view over the target schema.
-
If the view is not updatable, then you can use
INSTEAD OF INSERTtriggers.
-
If the XML document does not perfectly map to the target database schema, then you can perform these actions:
-
Modify the target. Create an object-relational view over the target schema and make the view the new target.
-
Modify the XML document by using XSLT to transform the XML document. You can register the XSLT stylesheet with XSU so that the incoming XML is automatically transformed before it attempts any mapping.
-
Modify XSU's XML-to-SQL mapping. You can instruct XSU to perform case-insensitive matching of XML elements to database columns or attributes. For example, you can instruct XSU to do this:
-
Use the name of the element corresponding to a database row instead of
ROW. -
Specify the date format to use when parsing dates in the XML document.
-
13.5.1.3 Customizing Generated XML
In some situations, you might need to generate XML with a specific structure. Because the desired structure might differ from the default structure of the generated XML document, you need to have some flexibility in this process.
Topics:
- Altering the Database Schema or SQL Query
You can perform source customizations by altering the SQL query or the database schema. - Modifying XSU
XSU lets you modify the rules that it uses to transform SQL data into XML.
13.5.1.3.1 Altering the Database Schema or SQL Query
You can perform source customizations by altering the SQL query or the database schema.
The simplest and most powerful source customizations include:
-
In the database schema, create an object-relational view that maps to the desired XML document structure.
-
In your query, do this:
-
Use cursor subqueries or cast-multiset constructs to create nesting in the XML document that comes from a flat schema.
-
Alias column and attribute names to get the desired XML element names.
-
Alias top-level scalar type columns with identifiers that begin with the at sign (@) to make them map to an XML attribute instead of an XML element. For example, executing these statement generates an XML document in which the
<ROW>element has the attributeempno:SELECT employee_name AS "@empno",... FROM employees;
-
Consider the customer.xml document shown in Example 13-14.
Suppose you must design a set of database tables to store this data. Because the XML is nested more than one level, you can use an object-relational database schema that maps canonically to the preceding XML document. Run the createObjRelSchema2.sql script in SQL*Plus to create such a database schema.
You can load the data in the customer.xml document into the customer_tab table created by the script. Invoke XSU for Java from the command line:
java OracleXML putXML -user "hr/password" -fileName customer.xml customer_tab
To load customer.xml into a database schema that is not object-relational, you can create objects in views on top of a standard relational schema. For example, you can create a relational table that contains the necessary columns, then create a customer view that contains a customer object on top of it, as shown in the createRelSchema.sql script in Example 13-15.
You can load data into customer_view:
java OracleXML putXML -user "hr/password" -fileName customer.xml customer_view
Alternatively, you can flatten your XML with XSLT and then insert it directly into a relational schema. However, this is the least recommended option.
To map a particular column or a group of columns to an XML attribute instead of an XML element, you can create an alias for the column name and prepend the at sign (@) before the name of this alias. For example, you can use the mapColumnToAtt.sql script to query the hr.employees table, rendering employee_id as an XML attribute.
You can run the mapColumnToAtt.sql script from the command line:
java OracleXML getXML -user "hr/password" -fileName "mapColumnToAtt.sql"Note:
All attributes must appear before any nonattribute.
Example 13-14 customer.xml
<?xml version = "1.0"?>
<ROWSET>
<ROW num="1">
<CUSTOMER>
<CUSTOMERID>1044</CUSTOMERID>
<FIRSTNAME>Paul</FIRSTNAME>
<LASTNAME>Astoria</LASTNAME>
<HOMEADDRESS>
<STREET>123 Cherry Lane</STREET>
<CITY>SF</CITY>
<STATE>CA</STATE>
<ZIP>94132</ZIP>
</HOMEADDRESS>
</CUSTOMER>
</ROW>
</ROWSET>
Example 13-15 createRelSchema.sql
CREATE TABLE hr.cust_tab
( customerid NUMBER(10),
firstname VARCHAR2(20),
lastname VARCHAR2(20),
street VARCHAR2(40),
city VARCHAR2(20),
state VARCHAR2(20),
zip VARCHAR2(20)
);
CREATE VIEW customer_view
AS
SELECT customer_type(customerid, firstname, lastname,
address_type(street,city,state,zip)) customer
FROM cust_tab;
13.5.1.3.2 Modifying XSU
XSU lets you modify the rules that it uses to transform SQL data into XML.
You can make any of these changes when mapping SQL to XML:
-
Change or omit the
<ROWSET>or<ROW>tag. -
Change or omit the attribute
num, which is the cardinality attribute of the<ROW>element. -
Specify the case for the generated XML element names.
-
Specify that XML elements corresponding to elements of a collection must have a cardinality attribute.
-
Specify the format for dates in the XML document.
-
Specify that null values in the XML document must be indicated with a nullness attribute rather than by omitting the element.
13.5.2 How XSU Processes SQL Statements
How XSU processes SQL statements is described.
Topics:
- How XSU Queries the Database
XSU executes SQL queries and retrieves theResultSetfrom the database. XSU then acquires and analyzes metadata about theResultSet. - How XSU Inserts Rows
The steps that XSU performs when inserting an XML document into a table or view are described. - How XSU Updates Rows
Updates and delete statements differ from inserts in that they can affect more than one row in the database table. - How XSU Deletes Rows
For row deletions, you can choose to provide a set of key columns, so that XSU can identify the rows to be deleted. If you do not provide a set of key columns then theDELETEstatement tries to match all the columns in the document. - How XSU Commits After DML
By default, XSU performs no explicit commits. IfAUTOCOMMITis on, which is the default for a JDBC connection, then after each batch of statement executions XSU executes aCOMMIT.
13.5.2.1 How XSU Queries the Database
XSU executes SQL queries and retrieves the ResultSet from the database. XSU then acquires and analyzes metadata about the ResultSet.
Using the mapping described in Default SQL-to-XML Mapping, XSU processes the SQL result set and converts it into an XML document.
XSU cannot handle certain types of queries, especially those that mix columns of type LONG or LONG RAW with CURSOR() expressions in the SELECT clause. LONG and LONG RAW are two examples of data types that JDBC accesses as streams and whose use is deprecated. If you migrate these columns to CLOBs, then the queries succeed.
13.5.2.2 How XSU Inserts Rows
The steps that XSU performs when inserting an XML document into a table or view are described.
When inserting the contents of an XML document into a table or view, XSU does the following:
-
Retrieves metadata about the target table or view.
-
Generates a SQL
INSERTstatement based on the metadata. For example, assume that the target table isdept1and the XML document is generated fromdept1. XSU generates thisINSERTstatement:INSERT INTO dept1 (deptno, deptname, deptaddr, emplist) VALUES (?,?,?,?)
-
Parses the XML document, and for each record, it binds the appropriate values to the appropriate columns or attributes. For example, it binds the values for
INSERTstatement:deptno <- 100 deptname <- SPORTS deptaddr <- AddressType('100 Redwood Shores Pkwy','Redwood Shores', 'CA','94065') emplist <- EmployeeListType(EmployeeType(7369,'John',100000, AddressType('300 Embarcadero','Palo Alto','CA','94056'),...) -
Executes the statement. You can optimize
INSERTprocessing to insert in batches and commit in batches.
Related Topics
See Also:
Inserting Rows with OracleXMLSave for more detail on batching
13.5.2.3 How XSU Updates Rows
Updates and delete statements differ from inserts in that they can affect more than one row in the database table.
For inserts, each <ROW> element of the XML document can affect at most one row in the table if no triggers or constraints are on the table. With updates and deletes, the XML element can match more than one row if the matching columns are not key columns in the table.
For update statements, you must provide a list of key columns that XSU must identify the row to update. For example, assume that you have an XML document that contains this fragment:
<ROWSET>
<ROW num="1">
<DEPTNO>100</DEPTNO>
<DEPTNAME>SportsDept</DEPTNAME>
</ROW>
</ROWSET>
You want to change the DEPTNAME value from Sports to SportsDept. If you supply the DEPTNO as the key column, then XSU generates this UPDATE statement:
UPDATE dept1 SET deptname = ? WHERE deptno = ?
XSU binds the values in this way:
deptno <- 100
deptname <- SportsDept
For updates, you can also choose to update only a set of columns and not all the elements present in the XML document.
Related Topics
13.5.2.4 How XSU Deletes Rows
For row deletions, you can choose to provide a set of key columns, so that XSU can identify the rows to be deleted. If you do not provide a set of key columns then the DELETE statement tries to match all the columns in the document.
Assume that you pass this document to XSU:
<ROWSET>
<ROW num="1">
<DEPTNO>100</DEPTNO>
<DEPTNAME>Sports</DEPTNAME>
<DEPTADDR>
<STREET>100 Redwood Shores Pkwy</STREET>
<CITY>Redwood Shores</CITY>
<STATE>CA</STATE>
<ZIP>94065</ZIP>
</DEPTADDR>
</ROW>
<!-- additional rows ... -->
</ROWSET>
XSU builds a DELETE statement for each ROW element:
DELETE FROM dept1 WHERE deptno = ? AND deptname = ? AND deptaddr = ?
The binding is:
deptno <- 100
deptname <- sports
deptaddr <- addresstype('100 redwood shores pkwy','redwood city','ca',
'94065')Related Topics
13.5.2.5 How XSU Commits After DML
By default, XSU performs no explicit commits. If AUTOCOMMIT is on, which is the default for a JDBC connection, then after each batch of statement executions XSU executes a COMMIT.
You can override this behavior by turning AUTOCOMMIT off and then using setCommitBatch to specify the number of statement executions before XSU commits. If an error occurs, then XSU rolls back to either the state the target table was in before the call to XSU, or the state after the last commit made during the current call to XSU.


