DBMS_XMLGEN is a built-in package that converts SQL query results into XML-formatted Character Large Object (CLOB) data. Use it to export relational data as XML for data exchange or integration with external systems.
Prerequisites
Before you begin, ensure that you have:
A PolarDB for PostgreSQL (Compatible with Oracle) cluster running Oracle syntax compatibility 2.0, minor engine version 2.0.14.17.35.0 or later
To check your minor engine version, view the minor engine version in the console or run SHOW polardb_version;. If the version is earlier than required, upgrade the minor engine version.
How it works
DBMS_XMLGEN maps relational data to XML using these default rules:
Each SQL result row maps to a
<ROW>element.Each column maps to a child element of
<ROW>, named after the column.The full result set is wrapped in a
<ROWSET>element.
Two usage patterns are available:
Direct conversion: Pass an SQL query string to
getXML. Use this for simple, one-off exports.Context-based conversion: Create a context handle with
newContext, callgetXMLto generate XML, then release resources withcloseContext. Use this pattern for complex or multi-step logic, or when you need to control output formatting.
Subprogram overview
The following subprograms are supported.
| Subprogram | Description |
|---|---|
convert(xmlData CLOB, flag) | Encodes or decodes XML special characters. Input: CLOB |
convert(xmlData VARCHAR2, flag) | Encodes or decodes XML special characters. Input: VARCHAR2 |
getXML(sqlQuery, dtdOrSchema) | Converts an SQL query result to XML and returns a CLOB |
newContext | Creates a context handle from an SQL query |
getXML(ctx, dtdOrSchema) | Generates XML from a context handle and returns a CLOB |
getXML(ctx, tmpclob, dtdOrSchema) | Generates XML from a context handle and writes it into an existing CLOB variable |
closeContext | Closes the context handle and releases associated resources |
Get started
Prepare data
The examples in the following sections use the employees table. Run the following SQL statements in your cluster to create and populate the table.
-- Create the employees table
CREATE TABLE employees (
"EMP_id" NUMBER,
name VARCHAR2(50),
dept VARCHAR2(30),
"SALARY" NUMBER
);
-- Insert test data
INSERT INTO employees VALUES (1, 'Zhang San', 'Technical Department', 15000);
INSERT INTO employees VALUES (2, 'Li Si', 'Finance Department', 12000);
INSERT INTO employees VALUES (3, 'Wang Wu', 'Technical Department', 18000);Generate XML directly from an SQL query
Use getXML with a query string for simple, one-off conversions.
Syntax
DBMS_XMLGEN.GETXML (
sqlQuery IN VARCHAR2,
dtdOrSchema IN number := NONE)
RETURN CLOB;| Parameter | Description |
|---|---|
sqlQuery | The SQL query to execute |
dtdOrSchema | Not supported |
Example
SELECT DBMS_XMLGEN.getXML('SELECT * FROM employees') FROM dual;Output:
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMP_id>1</EMP_id>
<name>Zhang San</name>
<dept>Technical Department</dept>
<SALARY>15000</SALARY>
</ROW>
<ROW>
<EMP_id>2</EMP_id>
<name>Li Si</name>
<dept>Finance Department</dept>
<SALARY>12000</SALARY>
</ROW>
<ROW>
<EMP_id>3</EMP_id>
<name>Wang Wu</name>
<dept>Technical Department</dept>
<SALARY>18000</SALARY>
</ROW>
</ROWSET>Generate XML using a context handle
Use the context-based pattern when you need finer control over the lifecycle of resources or want to configure output options.
Call
newContextwith an SQL query to create a context handle.Call
getXMLwith the handle to retrieve XML.Call
closeContextto release the handle and free resources.
Syntax
-- Create a context handle
DBMS_XMLGEN.NEWCONTEXT (
query IN VARCHAR2)
RETURN ctxHandle;
-- Generate XML from the handle (returns a new CLOB)
DBMS_XMLGEN.GETXML (
ctx IN ctxHandle,
dtdOrSchema IN number := NONE)
RETURN CLOB;
-- Generate XML from the handle (writes into an existing CLOB variable)
DBMS_XMLGEN.GETXML (
ctx IN ctxHandle,
tmpclob IN OUT NCOPY CLOB,
dtdOrSchema IN number := NONE);
-- Close the context
DBMS_XMLGEN.CLOSECONTEXT (
ctx IN ctxHandle);Example: Return XML as a new CLOB
DECLARE
xml_result CLOB;
handle DBMS_XMLGEN.ctxHandle;
BEGIN
handle := DBMS_XMLGEN.NEWCONTEXT('SELECT * FROM employees');
DBMS_OUTPUT.PUT_LINE(handle);
xml_result := DBMS_XMLGEN.GETXML(handle);
DBMS_OUTPUT.PUT_LINE(xml_result);
END;
/Example: Write XML into an existing CLOB variable
DECLARE
xml_result CLOB := '<dummy></dummy>';
handle DBMS_XMLGEN.ctxHandle;
BEGIN
handle := DBMS_XMLGEN.NEWCONTEXT('SELECT * FROM employees');
DBMS_OUTPUT.PUT_LINE(handle);
DBMS_XMLGEN.GETXML(handle, xml_result);
DBMS_OUTPUT.PUT_LINE(xml_result);
END;
/Encode and decode XML special characters
Use convert to escape or unescape special characters in XML strings.
| Original character | Escaped character |
|---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
Syntax
-- Input: VARCHAR2
DBMS_XMLGEN.CONVERT (
xmlData IN VARCHAR2,
flag IN NUMBER := ENTITY_ENCODE)
RETURN VARCHAR2;
-- Input: CLOB
DBMS_XMLGEN.CONVERT (
xmlData IN CLOB,
flag IN NUMBER := ENTITY_ENCODE)
RETURN CLOB;| Parameter | Description |
|---|---|
xmlData | The string to process |
flag | ENTITY_ENCODE or 0 (default): encodes special characters. ENTITY_DECODE or 1: decodes special characters |
Example
-- Encode special characters
SELECT DBMS_XMLGEN.CONVERT('<>&"''') FROM dual;
-- Returns: <>&"'
-- Decode back to original characters
SELECT DBMS_XMLGEN.CONVERT('<>&"'', 1) FROM dual;
-- Returns: <>&"'Usage notes
PolarDB for PostgreSQL (Compatible with Oracle) differs from Oracle in the following ways when using DBMS_XMLGEN.
Column name case
In PolarDB, unquoted column names are lowercase by default. In Oracle, they are uppercase by default. This affects the XML tag names generated by getXML.
If the downstream system accepts lowercase tags, no action is needed.
If the downstream system requires uppercase tags (for example,
/ROWSET/ROW/COLUMN_NAME), set thepolar_dbms_xmlgen_upper_column_type_nameparameter toONin the console.
Column aliases for function calls and constants
When a query contains a function call or a constant — for example:
SELECT DBMS_XMLGEN.getXML('SELECT my_function(1) FROM dual') FROM dual;The column name in the returned XML differs between Oracle and PolarDB:
Oracle:
MY_FUNCTION_x0028_1_x0029_(Unicode-formatted string)PolarDB:
my_function
To get consistent behavior, add an explicit alias to the function call:
SELECT DBMS_XMLGEN.getXML('SELECT my_function(1) AS column_name FROM dual') FROM dual;With an explicit alias, PolarDB and Oracle produce the same column name in the XML output.
Functions that return no rows
If an SQL statement returns 0 rows, getXML returns NULL, which is compatible with Oracle. However, if you wrap a function that raises no_data_found inside a getXML call — for example:
SELECT DBMS_XMLGEN.getXML('SELECT func_return_null FROM dual') FROM dual;Where func_return_null is defined as:
CREATE OR REPLACE FUNCTION func_return_null RETURN int AS
result int := 1;
BEGIN
-- Always returns 0 rows, triggers the no_data_found exception, and directly returns NULL
SELECT 1 INTO result FROM dual WHERE 1 = 0;
RETURN result;
END;
/The result may be incompatible with Oracle. Avoid this pattern.