IBM Support

7.1版本 DB2 for i 中的XML数据类型介绍

Technical Blog Post


Abstract

7.1版本 DB2 for i 中的XML数据类型介绍

Body

DB2 for i 7.1版本中我们加入了一项非常令人激动的功能,那就是对XML数据类型的支持。在这篇文章中,我将要给大家介绍一下如何在DB2中使用XML数据类型。

 

1.  建立跟XML相关的DB2对象。

跟其他的数据类型一样,你可以基于XML类型创建几乎所有的数据对象。如数据表,存储过程,用户自定义的函数,甚至于7.1版本中新加入的全局变量。当然,你也可以利用ALTER语句为你已有的DB2对象添加XML类型。比如

 

CREATE TABLE XMLTB(key int, xmlcol XML CCSID 1208);

ALTER TABLE XMLTB ADD COLUMN xmlcol2 XML CCSID 1200;

 

上面创建的数据表XMLTB中,xmlcol就被声明成为XML数据类型。你可以看到,该例中把XML数据类型的CCSID声明为1208UTF-8)。XML数据类型支持单字节编码,双字节编码,混合编码,二进制编码以及Unicode字符集。在创建一个数据表时,你可以显式的写入CCSID语句,也可以利用一个QAQQINI参数SQL_XML_DATA_CCSID来设置默认的CCSID值。例如:

 

Command Line下执行:

CRTDUPOBJ OBJ(QAQQINI) FROMLIB(QSYS) OBJTYPE(*FILE) TOLIB(WYTEST) DATA(*YES);                                                  

CHGQRYA QRYOPTLIB(WYTEST) ;

进入ISQL执行:

UPDATE WYTEST.QAQQINI SET QQVAL = 500

WHERE QQPARM = 'SQL_XML_DATA_CCSID'  ;

CREATE TABLE XMLTB(key int, xmlcol XML);

 

这个时候,XMLTB中的xmlcolCCSID就被定义为500

对于SQL_XML_DATA_CCSID而言,其默认的CCSID1208UTF-8)。这是符合国际上对于XML的标准的。也就是说,如果你将SQL_XML_DATA_CCSID的值设置为*DEFAULT的时候,系统会默认给XML数据列赋予1208CCSID值。

 

对于存储过程的参数,用户自定义的参数以及全局变量而言,他们的CCSID值的设置也是用同样的方式。比如,你可以通过对SQL_XML_DATA_CCSID的设置来修改一个存储过程参数列表中XML参数的CCSID

 

 

2.  XML的验证,解析和序列化。

DB2 提供了三个非常有用的内置函数:XMLVALIDATE , XMLPARSE以及XMLSERIALIZE。这三个函数会在很多跟XML数据类型相关的使用场景中一展身手。XMLVALIDATE 用来对某个特定的XML文档进行验证。这种验证是基于XML Schema的。 这个函数可以帮助你判断传入的XML文档是否满足特定XML Schema的要求,可以帮助你检查相应的XML的属性是否符合规定。这里有多种方式可以供你选择:

你可以通过传入的XML文档自带的XML Schema地址的信息,对XML文档进行检验:

INSERT INTO T1(XMLCOL)

       VALUES (XMLVALIDATE(xmldoc));

      而上面的插入语句中,xmldoc的内容如下:

<po:order

      xmlns:po='http://my.world.com'

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://my.world.com/world.xsd" >

    ...

</po:order>

 

XMLVALIDATE 函数中可以使用 ACCORDING TO XMLSCHEMA ID 显式的指定用于验证的 XML 模式文档(XML Schema) 如果没有明确指定,数据库会根据 XML 实例文档的命名空间 xsi:schemaLocation 或者 xsi:noNamespaceSchemaLocation 属性来确定用于验证的模式文档。

例如:

INSERT INTO T1(XMLCOL)

     VALUES(

        XMLVALIDATE(? ACCORDING TO XMLSCHEMA ID PODOCS.WORLDPO));

其中PODOCS.WORLDPO就是在系统中已经注册过的XML Schema象。如果XML模式文档在XMLVALIDATE函数中指定,则 xsi:schemaLocation 或者 xsi:noNamespaceSchemaLocation 属性被覆盖。

 

你还可以根据某一XML SchemaURI地址对传入的XML文档进行验证:

INSERT INTO T1(XMLCOL)

     VALUES(

        XMLVALIDATE(? 

          ACCORDING TO XMLSCHEMA URI 'http://my.world.com'

                 LOCATION 'http://my.world.com/world.xsd')) ;

 

XMLPARSE XMLSERIALIZE 是两个相反的操作。XMLPARSE是把一个符合XML格式的字符串类转换成XML数据类型。恰恰相反,XMLSERIALIZE是把一个XML数据类型转换成字符串。凡是使用到这两个函数时,我们叫做显示的进行XML解析或者显示的进行XML序列化。DB2 for i 7.1版本在一些情况下支持隐式的XML解析或者序列化,我们将在下一小节介绍。

在对XML数据类型做操作时,就可以显式使用XMLPARSE函数,例如:

1)  XML数据类型进行插入或者更新时:

INSERT INTO xmltable (xmlcol) VALUES(XMLPARSE(DOCUMENT ‘<a/>’)) ;

UPDATE xmltable set xmlcol = XMLPARSE(DOCUMENT ‘<a/>’) ;

 

2)  XML数据类型的PL变量进行赋值时:

SET xmlVar = XMLPARSE(DOCUMENT ‘<a/ >’) ;

 

3)  联合XMLVALIDATE函数一起使用时:

INSERT INTO T1(XMLCOL)

     VALUES(XMLVALIDATE(XMLPARSE(DOCUMENT ‘<a/>’)

 ACCORDING TO XMLSCHEMA ID PODOCS.WORLDPO));

 

4)  给以XML数据类型为参数的存储过程或者函数传入参数时。

Create function func1(P1 XML) returns XML

LANGUAGE SQL

RETURN P1;

VALUES(func1(XMLPARSE(document ‘<a/>’)));

 

如果要把XML数据类型跟字符串数据类型做交互,那么可以显式使用XMLSERIALIZE函数,例如:

1)  对字串数据类型进行插入或者更新时:

Create variable globalXMLVar XML ;

SET globalXMLVar = XMLPARSE(document ‘<a/>’) ;

INSERT INTO T1(CHARCOL) VALUES(XMLSERIALIZE(content globalXMLVar as char(5)) ;

 

2)  给存储过程或者函数传入字符串类型的参数时;

CREATE FUNCTION xmlFunc( clobParam clob(10) )

RETURNS XML

LANGUAGE SQL

RETURN XMLPARSE(document clobParam);

 

VALUES xmlFunc(XMLSERIALIZE(content globalXMLVar as clob(10)) );

 

3.  XML的赋值。

通常情况下,XML数据类型只能给XML数据类型进行赋值。但是由于引入了隐式序列化和隐式解析的概念,所以XML在赋值时有一些更为灵活的情况。XML数据类型可以隐式的序列化为字符串数据类型;同样的,字符串类型在某些情况下也可以隐式的解析成XML数据类型。

基本来讲,除了XML数据类型给XML数据类型赋值以外,还有如下四种特殊情况:

1)  在嵌入式SQL中对XML的宿主变量进行赋值。这种情况相对比较特殊。在嵌入式SQL中,XML类型的宿主变量按照类似于下面的方式进行声明:

SQL TYPE IS XML AS CHAR(100); 除了CHAR之外其他字串类型都可以在声明XML宿主变量时使用类似方法

可以看出XML类型的宿主变量从本质上来讲其结构还是字串类型。在跟DB2交互的过程中,这样的XML宿主变量被识别并进行隐式的解析。

 

2)  将字串类型赋值给XML类型的parameter marker。我们可以给XML类型的parameter marker绑定字串类型的变量。所以我们可以给类似于下面的语句中的parameter marker绑定字串类型:

UPDATE xmltable SET xmlcol = CAST(? AS XML) where id = 1;

 

3)  用字串类型改变数据表中XML列的值时。这样的情况通常发生在对XML数据列进行更新或者插入操作时。比如我们可以直接用字串类型对XML数据列进行如下操作:

INSERT INTO xmltable1 (intCol, xmlCol) VALUES (1, ’<a/>’);

UPDATE xmltable1 SET xmlCol = ’<b/>’ WHERE intcol = 1;

4)  XML类型进行取值并赋予字串类型时。我们可以使用SELECT INTO或者FETCH语句给宿主变量进行赋值。使用该方法用XML类型给字串赋值时,会发生隐式的序列化。如下例:

EXEC SQL DECLARE strVar VARCHAR(10);

EXEC SQL SELECT xmlCol INTO :strVar from xmltable1 where id = 1;

 

4.  带注释的 XML 模式分解( XML Decompostion Annotations )。在 7.1 版本中DB2 支持带有注释的模式分解。该功能可以把一个 XML 文档全部的或者部分的分解成数据库的关系表,并根据 XML 模式中的注释,将 XML 文档中的信息映射到关系表当中。具体的相关内容,我们会有后续的介绍。


5.  XML相关的函数。除了前面介绍的XMLPARSEXMLSERIALIZE函数之外7.1 版本的DB2还提供了一系列跟XML数据类型相关的内置函数以及发布函数publishing functions)。7.1 版本提供的发布函数可以用来构造 XML 的值。多种 XML 发布函数按照一定的顺序联合使用,会构造出满足不同客户要求的 XML。比如

XMLATTRIBUTES, XMLCOMMENT, XMLCONCAT, XMLDOCUMENT, XMLELEMENT, XMLFOREST, XMLNAMESPACE, XMLPI, XMLROW, XMLTEXT, XMLTRANSFORM等等。这些函数大大丰富了数据库对XML文档以及数据类型的操作。我们后面在Blog中还会对他们进行具体的介绍。

 

XML数据类型的相关概念以及应用很多,我们在后续的文章中会针对 XML publishing 函数,XML 模式解析,XML CCSID等等有更多的介绍。

[{"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG60","label":"IBM i"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB57","label":"Power"}}]

UID

ibm11146232