金仓数据库KingbaseES 兼容Oracle包dbms_xmlgen的使用
关键字:
Kingbase、dbms_xmlgen、xml、人大金仓、KingbaseES、
一、dbms_xmlgen包概述
1.1 定义
(1)dbms_xmlgen:将SQL查询结果转换为XML文档,将XML文档以CLOB或XMLType形式返回。
(2)包中定义类型
类型名 | 描述 |
ctxHandle | 查询字符串的上下文句柄类型,在Kingbase中,实质为sys_refcursor类型,由NEWCONTEXT函数返回 |
1.2 功能
dbms_xmlgen包的功能为将SQL查询结果转化为XML文档,转化方式一共分为两种:
(1) 通过查询字符串获取XML文档。
(2) 通过上下文句柄获取XML文档。
对于通过查询字符串获取XML文档的方式,只需要将查询字符串输入到GETXML或GETXMLTYPE函数中,就可以直接获取查询字符串对应的XML文档,无需进行其他操作。
而对于通过上下文句柄获取XML文档的方式,返回查询字符串对应的XML文档需要进行以下几步操作:
(1)创建上下文句柄。
(2)设置句柄属性
(3)获取XML文档。
(4)获取处理的行数。
(5)关闭上下文句柄。
用户可以通过输入查询字符串或查询字符串引用的游标来创建上下文句柄,并对上下文句柄设置不同的属性来获取各种不同形式的XML文档。如果用户不对句柄属性进行设置,dbms_xmlgen包则采用创建上下文句柄时的默认设置来获取XML文档。在XML文档获取之后,如果想要获取处理的行数,dbms_xmlgen包提供了GETNUMROWSPROCESSED函数,用户可以通过该函数进行获取。为节省空间和资源,在句柄使用完毕后,用户可以通过调用CLOSECONTEXT过程将句柄关闭,释放句柄属性资源。
对于获取的XML文档,兼容Oracle包dbms_xmlgen提供了转义接口,用户可以将获取的XML文档输入到CONVERT函数中,CONVERT函数可以将XML文档中的特殊字符(预定义实体)进行转义。其中,转义的范围不仅包括XML内容,还包括标签。
二、dbms_xmlgen包使用
根据第1.2节功能描述,可以将dbms_xmlgen包子程序分为五大类:创建上下文句柄、设置句柄属性、获取XML文档、获取处理行数、关闭上下文句柄、将XML文档进行转义。
分类 | 过程/函数 | 描述 |
创建上下文句柄 | NEWCONTEXT函数 | 创建上下文句柄 |
设置句柄属性 | SETCONVERTSPECIALCHAR过程 | 设置生成XML文档中特殊字符是否转义 |
SETMAXROWS过程 | 设置每次调用GETXML函数时需要获取的最大行数 | |
RESTARTQUERY过程 | 重新启动查询以从头开始获取XML文档 | |
SETNULLHANDLING过程 | 设置XML文档中对NULL值的表示方法 | |
SETROWSETTAG过程 | 设置XML文档中根标签的名称 | |
SETROWTAG过程 | 设置XML文档中行标签的名称 | |
SETSKIPROWS过程 | 设置每次调用GETXML函数时跳过的行数 | |
USEITEMTAGSFORCOLL过程 | 设置生成的XML文档中集合类型元素的标签名为列名_item | |
USENULLATTRIBUTEINDICATOR过程 | 设置是否使用一个XML属性来表示NULL,或者忽略NULL | |
获取XML文档 | GETXML函数 | 获取XML文档,并以CLOB形式返回 |
GETXMLTYPE函数 | 获取XML文档,并以XMLTYPE形式返回 | |
获取处理行数 | GETNUMROWSPROCESSED函数 | 获取调用GETXML函数时处理的行数 |
关闭上下文句柄 | CLOSECONTEXT过程 | 关闭上下文并释放所有资源 |
将XML文档进行转义 | CONVERT函数 | 转义或反转义XML文档中的特殊字符 |
2.1 典型示例
(1)在KES中,dbms_xmlgen包的实现依赖于kdb_xmltype插件,因此,在创建dbms_xmlgen包之前,需要创建kdb_xmltype插件。
create extension kdb_xmltype;
create extension dbms_xmlgen;
(2)创建表格test1、test2,并插入数据,这两个表格用于select查询,将select查询字符串输入到dbms_xmlgen包中newcontext函数,可以生成上下文句柄,用于后续生成XML文档。
create table test1 (id int, name text);
insert into test1 values(1, 'aaa'), (2, 'bbb'), (3, NULL);
(3)创建表格xml_test,xml_test用于存放生成的XML文档结果,该示例不进行句柄属性设置,包括创建上下文句柄、获取XML文档、关闭上下文句柄步骤:
test=# \set SQLTERM /
test=# create table xml_test (result CLOB);
test-# declare
test-# lcontext dbms_xmlgen.ctxhandle;
test-# lxmldata CLOB;
test-# begin
test-# lcontext := dbms_xmlgen.newcontext('select * from test1');
test-# lxmldata := dbms_xmlgen.getxml(lcontext, 0);
test-# insert into xml_test values(lxmldata);
test-# dbms_xmlgen.closecontext(lcontext);
test-# end;
test-# /
CREATE TABLE
ANONYMOUS BLOCK
test=# select * from xml_test;
test-# /
<?xml version = "1.0"?>+
<rowset> +
<row> +
<id>1</id> +
<name>aaa</name> +
</row> +
<row> +
<id>2</id> +
<name>bbb</name> +
</row> +
<row> +
<id>3</id> +
</row> +
</rowset> +
(4)创建表格xml_test1,xml_test1用于存放生成的XML文档结果,该示例设置了每次调用GETXML函数时最大处理数据行数,可以获取指定行数的XML文档,并且可以输出最后一次调用GETXML函数实际处理的行数。
test=# \set SQLTERM /
test=# create table xml_test1 (result CLOB);
test-# declare
test-# lcontext dbms_xmlgen.ctxhandle;
test-# lxmldata CLOB;
test-# lxmldata1 CLOB;
test-# num number;
test-# begin
test-# lcontext := dbms_xmlgen.newcontext('select * from test1');
test-# dbms_xmlgen.setmaxrows(lcontext,1);
test-# lxmldata := dbms_xmlgen.getxml(lcontext, 0);
test-# lxmldata1 := dbms_xmlgen.getxml(lcontext, 0);
test-# insert into xml_test1 values(lxmldata);
test-# insert into xml_test1 values(lxmldata1);
test-# num := dbms_xmlgen.getnumrowsprocessed(lcontext);
test-# dbms_output.put_line('Processed Rows is:'||num);
test-# dbms_xmlgen.closecontext(lcontext);
test-# end;
test-# /
CREATE TABLE
ANONYMOUS BLOCK
Processed Rows is:1
test=# select * from xml_test1;
test-# /
<?xml version = "1.0"?>+
<rowset> +
<row> +
<id>1</id> +
<name>aaa</name> +
</row> +
</rowset> +
<?xml version = "1.0"?>+
<rowset> +
<row> +
<id>2</id> +
<name>bbb</name> +
</row> +
</rowset> +
三、总结
(1)Kingbase的dbms_xmlgen包依赖于kdb_xmltype包,因此,在创建dbms_xmlgen插件之前,需要创建kdb_xmltype插件。
(2)Kingbase会对XML文档进行合法性检查,字符<和&不符合XML文档内容规范,调用SETCONVERTSPECIALCHARS过程设置为不进行转义时,如果XML文档内容包含这两种字符,会输出报错,显示无效的XML内容。
(3)Kingbase中,XML标签命名规则为:
- 名称可以含字母、数字以及其他字符
- 名称不能以标点符号或者数字开始。
- 名称不能包含空格。