#DBMS_XMLGEN

DBMS_XMLGEN高级包提供了一组内置的存储过程、常量、数据结构,用于将查询的结果数据转换为标准的XML格式文档。

当前DBMS_XMLGEN高级包应用需遵循如下用法:

  • XMLGEN一次性转换XML格式的查询结果集大小不能超过64MB,如果查询结果集超过限定值请分批转换。
  • 支持转换成XML节点取值的查询结果数据最大长度不超过64KB。
  • 生成XML格式文档时,支持对文本中的特殊字符定义编码规则。

# 数据结构

DBMS_XMLGEN包中使用自定义数据类型作为函数参数或返回值。

SUBTYPE CTXHANDLE IS NUMBER;
SUBTYPE CTXTYPE IS NUMBER;
SUBTYPE CONVERSIONTYPE IS NUMBER;

# 预定义常量

DBMS_XMLGEN系统包定义了一组常量,供DBMS_XMLGEN高级包相关函数及子程序调用。下表为详细信息。

名称 数据类型 描述
NONE NUMBER 0 用于控制生成XML格式文档时是否生成元数据信息。
DTD NUMBER 1 生成XML格式文档时嵌入DTD <!DOCTYPE ...>,用于定义元素和属性的合法结构。
SCHEMA NUMBER 2 生成XML格式文档时嵌入XML Schema(XSD),用于定义XML文档的命名空间和SCHEMA。
ENTITY_ENCODE NUMBER 0 将文本中的特殊字符转换为对应的XML实体引用(entity references),以确保这些字符在XML中被安全解析,而不会破坏文档结构。
ENTITY_DECODE NUMBER 1 将XML文档中的实体引用还原为原始的特殊字符。
DROP_NULLS NUMBER 0 表示数据中的NULL值不会生成空的元素节点。
NULL_ATTR NUMBER 1 表示数据中的NULL值会生成完整的空的元素节点,并添加属性xsi:nil="true",其中xsi为XML文档的命名空间。
设置后,命名空间会变为:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"。
EMPTY_TAG NUMBER 2 表示数据中的NULL值以自闭合标签<TAG/>生成空值元素节点。

# 子程序说明

# CLOSECONTEXT Procedure

DBMS_XMLGEN.CLOSECONTEXT(ctx IN CTXHANDLE);

该存储过程用于结束XML格式文档生成操作,释放系统资源。

参数 用途
ctx 将NEWCONTEXT函数返回值作为入参。

# CONVERT Function

DBMS_XMLGEN.CONVERT(xmlData IN VARCHAR2, flag IN BIGINT DEFAULT ENTITY_ENCODE) RETURN VARCHAR2;

DBMS_XMLGEN.CONVERT(xmlData IN CLOB, flag IN BIGINT DEFAULT ENTITY_ENCODE) RETURN CLOB;

该函数用于将XML数据中的特殊符号转换成符合XML规范的实体。

该函数暂不支持入参为绑定参数。

参数 用途
xmlData 可以直接传入字符串类型的XML格式文档,也可以传入GETXML函数或子程序返回的CLOB类型的XML格式文档。
flag 用于配置对XML数据中特殊符号的转换方式。默认为ENTITY_ENCODE,也可以传入0,表示需要对XML数据中的特殊符号进行编码;传入其他非0数值或ENTITY_DECODE时,表示不对XML数据中的特殊符号进行编码。

此函数影响的特殊符号如下表所示。

符号 编码
& &
< <
> >
" "
' '

# GETNUMROWSPROCESSED Function

DBMS_XMLGEN.GETNUMROWSPROCESSED(ctx IN CTXHANDLE) RETURN NUMBER;

该函数用于获取本次生成XML格式文档需要处理的SQL查询结果数据总行数。

参数 用途
ctx 将NEWCONTEXT函数返回值作为入参。

# GETXML Function and Procedure

-- 存储过程
DBMS_XMLGEN.GETXML(ctx IN CTXHANDLE, tmpclob IN OUT NOCOPY clob, dtdOrSchema IN NUMBER DEFAULT NONE);

-- 函数
DBMS_XMLGEN.GETXML(ctx IN CTXHANDLE, dtdOrSchema IN NUMBER DEFAULT NONE) RETURN CLOB;
DBMS_XMLGEN.GETXML(sqlQuery IN VARCHAR2, dtdOrSchema IN NUMBER DEFAULT NONE) RETURN CLOB;

该函数将查询结果转换为XML文档格式,并以CLOB格式返回。

该函数暂不支持入参为绑定参数。

参数 用途
ctx 将NEWCONTEXT函数返回值作为入参。
sqlQuery 输入查询SQL语句。
tmpclob 将查询结果转成XML格式并以CLOB类型返回。
使用GEMXML子存储过程时,会将原始数据和转换后的数据拼接后返回。
dtdOrSchema 配置生成的XML格式文档是否包含DTD或Schema信息。
- 默认传入None,也可以传入0,表示不包含DTD和Schema信息;
- 入参传入1或DTD时,表示添加DTD信息。当前仅完成兼容性,无具体含义。
- 入参传入2或SCHEMA时,表示添加SCHEMA信息。当前仅完成兼容性,无具体含义。

# GETXMLTYPE Function and Procedure

-- 存储过程
DBMS_XMLGEN.GETXMLTYPE(ctx IN CTXHANDLE, tmpxmltype IN OUT NOCOPY XMLTYPE, dtdOrSchema IN NUMBER DEFAULT NONE);

-- 函数
DBMS_XMLGEN.GETXMLTYPE(ctx IN CTXHANDLE, dtdOrSchema IN NUMBER DEFAULT NONE) RETURN sys.XMLTYPE;
DBMS_XMLGEN.GETXMLTYPE(sqlQuery IN VARCHAR2, dtdOrSchema IN NUMBER DEFAULT NONE) RETURN sys.XMLTYPE;

该函数将查询结果转换为XML文档格式,并以XMLTYPE格式返回。

该函数暂不支持入参为绑定参数。

参数 用途
ctx 将NEWCONTEXT函数返回值作为入参。
sqlQuery 输入查询SQL语句。
tmpxmltype 将查询结果转成XML格式并以XMLTYPE类型返回。
使用GEMXMLTYPE子存储过程时,会将原始数据和转换后的数据拼接后返回。
dtdOrSchema 配置生成的XML格式文档是否包含DTD或Schema信息。
- 默认传入None,也可以传入0,表示不包含DTD和Schema信息;
- 入参传入1或DTD时,表示添加DTD信息。当前仅完成兼容性,无具体含义。
- 入参传入2或SCHEMA时,表示添加SCHEMA信息。当前仅完成兼容性,无具体含义。

# NEWCONTEXT Function

DBMS_XMLGEN.NEWCONTEXT(queryString IN VARCHAR2) RETURN CTXHANDLE;
DBMS_XMLGEN.NEWCONTEXT(queryString IN SYS_REFCURSOR) RETURN CTXHANDLE;

该函数用于传入SQL查询语句。

SQL查询语句可以通过入参直接传入字符串,也可以通过系统动态游标SYS_REFCURSOR传入,并返回CTXHANDLE。

# SETMAXROWS Procedure

DBMS_XMLGEN.SETMAXROWS(ctx IN CTXHANDLE, maxRows IN NUMBER);

该存储过程用于配置本次生成XML格式文档要处理的SQL查询数据的最大行数,如果SQL查询数据总行数超过配置值,达到配置值后结束XML格式转换。

参数 用途
ctx 将NEWCONTEXT函数返回值作为入参。
maxRows 配置最大转换行数。

# SETNULLHANDLING Procedure

DBMS_XMLGEN.SETNULLHANDLING(ctx IN CTXHANDLE, flag IN NUMBER DEFAULT DROP_NULLS);

该存储过程用于配置生成XML格式文档时对查询数据中列值为NULL的处理方式。

参数 用途
ctx 将NEWCONTEXT函数返回值作为入参。
flag 配置生成XML格式文档时对列值为NULL的处理方式。
- 默认传入DROP_NULLS,也可以传入0,表示不会生成空的元素节点;
- 入参传入1或NULL_ATTR时,表示生成完整的空的元素节点,并添加属性xsi:nil="true",其中xsi为XML文档的命名空间。设置后,命名空间会变为:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"。
- 入参传入2或EMPTY_TAG时,表示以自闭合标签<TAG/>方式生成空的元素节点。

# SETSKIPROWS Procedure

DBMS_XMLGEN.SETSKIPROWS(ctx IN CTXHANDLE, skipRows IN NUMBER);

该存储过程配置本次生成XML格式文档要跳过的SQL查询数据的最大行数,从配置值的下一行开始XML格式转换。

参数 用途
ctx 将NEWCONTEXT函数返回值作为入参。
skipRows 配置跳过行数。

# 示例

-- 创建表并插入数据
CREATE TABLE xmlgen_basic_employees (
                           employee_id NUMBER PRIMARY KEY,
                           first_name VARCHAR2(50),
                           last_name VARCHAR2(50),
                           email VARCHAR2(100),
                           department VARCHAR2(50),
                           salary NUMBER(10,2)
);

INSERT INTO xmlgen_basic_employees VALUES (1, 'John', 'Smith', 'john.smith@company.com', 'IT', 75000.00);
INSERT INTO xmlgen_basic_employees VALUES (2, 'Jane', 'Doe', 'jane.doe@company.com', 'HR', 65000.00);
INSERT INTO xmlgen_basic_employees VALUES (3, 'Michael', 'Johnson', 'michael.johnson@company.com', 'Finance', 80000.00);
INSERT INTO xmlgen_basic_employees VALUES (4, 'Sarah', 'Williams', 'sarah.williams@company.com', 'IT', 70000.00);
INSERT INTO xmlgen_basic_employees VALUES (5, 'David', 'Brown', 'david.brown@company.com', 'Marketing', 60000.00);
INSERT INTO xmlgen_basic_employees VALUES (6, 'Lisa', 'Davis', 'lisa.davis@company.com', 'HR', 68000.00);
INSERT INTO xmlgen_basic_employees VALUES (7, 'Robert', 'Miller', 'robert.miller@company.com', 'Finance', 85000.00);
INSERT INTO xmlgen_basic_employees VALUES (8, 'Jennifer', 'Wilson', 'jennifer.wilson@company.com', 'IT', 72000.00);
INSERT INTO xmlgen_basic_employees VALUES (9, NULL, 'Taylor', 'taylor@company.com', 'Marketing', 58000.00);
INSERT INTO xmlgen_basic_employees VALUES (10, 'Kevin', 'Anderson', NULL, 'Operations', 62000.00);

COMMIT;

-- 验证基础的XML格式文档生成能力
SELECT dbms_xmlgen.getxml('SELECT 1 AS "-A" FROM dual') FROM dual;

DBMS_XMLGEN.GETXML('SELECT1AS"-A"FROMDUAL')                      
---------------------------------------------------------------- 
<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
  <ROW>
    <_x002D_A>1</_x002D_A>
  </ROW>
</ROWSET>

-- 验证对特殊字符的编码能力,flag字段入参为空表示编码,flag入参为1表示不编码。
SELECT DBMS_XMLGEN.CONVERT('<>&"''') FROM dual;

DBMS_XMLGEN.CONVERT('<>&"''')                                  
---------------------------------------------------------------- 
&lt;&gt;&amp;&quot;&apos;                                       


SELECT DBMS_XMLGEN.CONVERT('<>&"''',1) FROM dual;

DBMS_XMLGEN.CONVERT('<>&"''',1)                                  
---------------------------------------------------------------- 
<>&"'   

以下示例为按CLOB类型生成XML格式文档,并控制空值为NULL_ATTR和DROP_NULLS处理方式。

DECLARE
    ctx_handle NUMBER;
    xml_result CLOB;
BEGIN
    DBMS_LOB.CREATETEMPORARY(xml_result);
    -- CREATE context FOR XML generation
    ctx_handle := DBMS_XMLGEN.newContext('SELECT employee_id, first_name, last_name, email FROM xmlgen_basic_employees WHERE employee_id IN (9, 10) ORDER BY employee_id');

    -- SET null handling TO show NULL VALUES AS empty tags (DEFAULT behavior)
    DBMS_XMLGEN.setNullHandling(ctx_handle, DBMS_XMLGEN.NULL_ATTR);

    -- Generate XML output WITH NULL attributes
    DBMS_OUTPUT.PUT_LINE('XML with NULL handling using NULL_ATTR:');
    xml_result := DBMS_XMLGEN.getXML(ctx_handle);
    DBMS_OUTPUT.PUT_LINE(xml_result);

    -- Reset context AND CHANGE null handling
    DBMS_XMLGEN.closeContext(ctx_handle);
    ctx_handle := DBMS_XMLGEN.newContext('SELECT employee_id, first_name, last_name, email FROM xmlgen_basic_employees WHERE employee_id IN (9, 10) ORDER BY employee_id');

    -- SET null handling TO omit NULL elements entirely
    DBMS_XMLGEN.setNullHandling(ctx_handle, DBMS_XMLGEN.DROP_NULLS);

    -- Generate XML output WITH omitted NULL VALUES
    DBMS_OUTPUT.PUT_LINE('XML with NULL handling using DROP_NULLS:');
    xml_result := DBMS_XMLGEN.getXML(ctx_handle);
    DBMS_OUTPUT.PUT_LINE(xml_result);

    -- CLOSE the context
    DBMS_XMLGEN.closeContext(ctx_handle);
    DBMS_LOB.FREETEMPORARY(xml_result);
END;
/

XML with NULL handling using NULL_ATTR:
<?xml version="1.0" encoding="UTF-8"?>
<ROWSET xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ROW>
    <EMPLOYEE_ID>9</EMPLOYEE_ID>
    <FIRST_NAME xsi:nil="true"/>
    <LAST_NAME>Taylor</LAST_NAME>
    <EMAIL>taylor@company.com</EMAIL>
  </ROW>
  <ROW>
    <EMPLOYEE_ID>10</EMPLOYEE_ID>
    <FIRST_NAME>Kevin</FIRST_NAME>
    <LAST_NAME>Anderson</LAST_NAME>
    <EMAIL xsi:nil="true"/>
  </ROW>
</ROWSET>

XML with NULL handling using DROP_NULLS:
<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
  <ROW>
    <EMPLOYEE_ID>9</EMPLOYEE_ID>
    <LAST_NAME>Taylor</LAST_NAME>
    <EMAIL>taylor@company.com</EMAIL>
  </ROW>
  <ROW>
    <EMPLOYEE_ID>10</EMPLOYEE_ID>
    <FIRST_NAME>Kevin</FIRST_NAME>
    <LAST_NAME>Anderson</LAST_NAME>
  </ROW>
</ROWSET>

以下示例为按XMLTYPE类型生成XML格式文档,并控制本次最多完成5行数据转换。

DECLARE
    ctx_handle NUMBER;
    xml_result xmltype;
    rows_processed NUMBER;
BEGIN
    -- CREATE context FOR XML generation
    ctx_handle := DBMS_XMLGEN.newContext('SELECT employee_id, first_name, last_name, department, salary FROM xmlgen_basic_employees ORDER BY salary DESC');

    -- LIMIT TO ONLY 5 ROWS maximum
    DBMS_XMLGEN.setMaxRows(ctx_handle, 5);

    -- Generate XML output
    xml_result := DBMS_XMLGEN.getXmltype(ctx_handle);

    -- Get NUMBER OF ROWS processed
    rows_processed := DBMS_XMLGEN.getNumRowsProcessed(ctx_handle);

    -- Display results
    DBMS_OUTPUT.PUT_LINE('Top 5 highest paid employees in XML format:');
    DBMS_OUTPUT.PUT_LINE(xml_result.getClobval());
    DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || rows_processed);

    -- CLOSE the context
    DBMS_XMLGEN.closeContext(ctx_handle);
END;
/

Top 5 highest paid employees in XML format:
<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
  <ROW>
    <EMPLOYEE_ID>7</EMPLOYEE_ID>
    <FIRST_NAME>Robert</FIRST_NAME>
    <LAST_NAME>Miller</LAST_NAME>
    <DEPARTMENT>Finance</DEPARTMENT>
    <SALARY>85000</SALARY>
  </ROW>
  <ROW>
    <EMPLOYEE_ID>3</EMPLOYEE_ID>
    <FIRST_NAME>Michael</FIRST_NAME>
    <LAST_NAME>Johnson</LAST_NAME>
    <DEPARTMENT>Finance</DEPARTMENT>
    <SALARY>80000</SALARY>
  </ROW>
  <ROW>
    <EMPLOYEE_ID>1</EMPLOYEE_ID>
    <FIRST_NAME>John</FIRST_NAME>
    <LAST_NAME>Smith</LAST_NAME>
    <DEPARTMENT>IT</DEPARTMENT>
    <SALARY>75000</SALARY>
  </ROW>
  <ROW>
    <EMPLOYEE_ID>8</EMPLOYEE_ID>
    <FIRST_NAME>Jennifer</FIRST_NAME>
    <LAST_NAME>Wilson</LAST_NAME>
    <DEPARTMENT>IT</DEPARTMENT>
    <SALARY>72000</SALARY>
  </ROW>
  <ROW>
    <EMPLOYEE_ID>4</EMPLOYEE_ID>
    <FIRST_NAME>Sarah</FIRST_NAME>
    <LAST_NAME>Williams</LAST_NAME>
    <DEPARTMENT>IT</DEPARTMENT>
    <SALARY>70000</SALARY>
  </ROW>
</ROWSET>

Number of rows processed: 5

edit-icon
反馈
coperate-icon
coperate
合作
communication-icon
communicate
交流