技术开发 频道

使用Pure XML技术查询DB2 Express-C数据库



    【IT168 专稿】自从去年IBM推出DB2 Viper后,最近又推出了一个免费的DB2版本:DB2 Express-C。这个版本虽然在CPU、内存上存在限制,但在功能上基本和DB2的收费版本是一样的。DB2 Express-C最令人振奋的功能就是全面引入了Pure XML技术。这就意味着以前人们普遍认为层次型和关系型数据库鱼和熊掌不能兼得的事实在DB2 9这里被打破。我们可以在DB2 Express-C中同时使用SQL和XQuery语言来查询数据,这两种语言可以单独使用,也可以互相嵌套使用。本文将讨论如何在DB2 Express-C中使用这些技术来查询数据。

    一、Pure XML技术简介

    DB2的PureXML技术可以使XML数据以xml字段类型保存在数据库中,而不是传统的CLOB类型字段。可样做可以使XML数据按层次格式保存在数据库中,可以提高查询XML数据的性能。而且XML数据还可以和关系型数据无缝集成,也就是说,可以将XML数据当面是DB2的普通表来对待。这样将大大增强处理XML数据的灵活性。在DB2 Express-C中可以使用三种方法来操作数据表。

    1. 普通的SQL语句。
    这些SQL语句中不带有任何的其他东西,这种方法是传统的数据库查询方法,但这种方式不能对XML数据内容进行查询。
    2. 在SQL中嵌入了 XQuery语句。
    这种方式以查询关系型数据为主,通过在SQL中嵌入XQuery,可以把XML数据当成一个表,并对其内部进行查询。
    3. 使用XQuery查询。
    可以单独使用XQuery对xml类型字段的内容进行查询,还可以在XQuery中嵌入SQL语句,这一点和第二种方法类似,但如果涉及到分组或排序等操作时,还是使用第二种方法为好。

    在上面提到的XQuery是XPath的超集,如果您只熟悉XPath,也不会影响您对DB2
Express-C的操作,因为光使用XPath的功能已经足够对XML数据进行查询了,在一般情况下,并不需要使用XQuery的扩展功能。

    二、建立实验数据表


    为了进行以后的实验,我们在这里建立三个实验表:table1、table2和table3。建立这两个表的SQL语句如下:

    create table table1( id char(4), xml_data xml)

    table1的部分数据如下

id xml_data 0001 <table1 id = "xxx"> <row id="0001"> <field1>xyz </field1> <fiield2>4321</field2> </row> <row id="0002"> <field1>aaa </field1> <fiield2>1234</field2> </row> </table1> 0002 <table1 id = "yyy"> <row id="0002"> <field1>uuu </field1> <fiield2>2211</field2> </row> <description>销售信息</description> </table1> ... ... ... ...
    create table unit( id char(4) primary key not null, name char(20))

    table2的部分数据如下
id name 0001 Bill Gates 0002 Mike ... ... ... ... create table table3(mydata xml)
    table3的部分数据如下
mydata <table3 id = "xxx"> <row id="0001"> <field1>xyz </field1> <fiield2>4321</field2> </row> <row id="0003"> <field1>aaa </field1> <fiield2>1234</field2> </row> </table3> ... ...


    三、普通的SQL查询

    对于XML数据来说,xml类型和CLOB类型字段可以达到同样的目的,就是将整个XML数据取出,不做任何处理送到客户端,只要客户端程序可以识别XML数据,就可以处理它们。我们可以使用如下的SQL来返回xml类型的数据:

    select xml_data from table1 where id = '0001'

    还可以将table1和table2做一下等值连接,以便返回更多的数据。

select table1.id, table2.name, table1.xml_data from table1,table2 where table1.id = table2.id and table2.name = 'Mike'
    从上面的两条SQL语句中可以看出,使用普通的SQL无法对XML数据更进一步地处理,而必须要客户端来过滤这些XML数据。如果只是返回整个XML文档,建议使用传统的VARCHAR或CLOB类型字段,因此,这种字段并不会对XML进行任何处理,如果只是简单地返回数据,在性能上可能会表现得更优越。
普通的SQL在不使用XQuery的情况下,也可以利用传统的DB2 Net Search扩展来进行全文检索。但这种方式要比XQuery方式的效率低。如下面的SQL返回table1中xml_data字段的field1节点包含字符串xyz的所有的XML文档数据。

select xml_data from table1 where CONTAINS(xml_data,'SECTION("/table1/row/field1") "xyz" ')=1;
    四、在SQL中嵌入XQuery/XPath

    在DB V8中,DB2已经加入了一些处理XML数据的功能,如用户可以使用XMLELEMENT、XMLATTRIBUTE、XMLFOREST、XMLAGG 和其他一些函数将关系型数据构造为XML。
在DB2 Express-C中,IBM又为其加入了很多可以使用XQuery或更简单的XPath表达式的功能,如XMLQUERY、XMLTABLE、XMLEXISTS等函数。如下面的SQL语句查询xml_data字段中所有table1节点的id属性值为为"xxx"并且id不小于"0010"的记录,并返回xml_data字段中field1节点的值。

SELECT id, XMLQUERY('for $e in $xd/table1/row return $e/field1/text()' passing d.xml_data as "xd") FROM table1 t1 WHERE id >= '0010' and XMLEXISTS('$xd/table1[@id = "xxx"]' passing t1.xml_data as "xd");
    上面的SQL语句的查询结果如下:
0010 xyz 0011 kkk … …


    上面的SQL语句显示了DB2 Express-C如何对XML内部数据进行查询,但这并不是PureXML的全部功能。PureXML还可以使用XMLTABLE将XML数据映射成一个表,使用COLUMNS子句将XML的一些节点映射成列,这些映射后的表和普通的关表的命名用方法一样。如上面的SQL还可用下面的SQL实现:

SELECT t1.id, tt.field1 FROM table1 d, XMLTABLE('for $emp in $xd/table1[@id=”xxx”]/row eturn $emp' passing t1.xml_data as
“xd” COLUMNS field1 varchar(
50) path 'field1/text()' ) as tt WHERE id >='0010'
    上面的SQL将每个row节点映射成一个表,并将field1节点映射成field1字段,并通过这个field1将所有满足条件的数据取出来。 使用XMLEXISTS还可以比较XML字段数据和关系表中的字段的值,如下面的SQL查询table1的xml_data字段和table2的name字段是否存相等的值。并返回table1的id字段。SQL语句如下:

SELECT t1.id FROM table1 t1, table2 t2 WHERE XMLEXISTS('$xd//row[field1 = $n]' passing t1.xml_data as "xd", t2.name as "n");
    上面的SQL语句还可以另外一种写方法:

SELECT t1.id FROM table1 t1, table2 t2 WHERE t2.name = XMLCAST(XMLQUERY('$xd//row/field1 ' passing xd.xml_data as "xd") as varchar(50));
    对于上面的两种实现方法,第一种要好一些。因为XMLCAST函数只需要一个值,而在这里XMLCAST中的语句如果field1节点有多个值满足条件时,就会返回多个值,这时这条语句将会执行失败。

    在SQL中嵌入XQuery或XPath的最大优势就是可以利用SQL强大的分组功能,如下面的SQL语句所示:

SELECT tt.f1,count(tt.f2) FROM table1, XMLTABLE ('$xd/table1/row' passing xml_data as "xd" COLUMNS f1 VARCHAR(50) PATH ' field1', f2 INTEGER PATH ' field2 ') as tt GROUP BY tt.f2
    上面的SQL语句按table1表的xml_data字段的field2节点进行分组,然后统计每组中field2节点的数量。
    在SQL中嵌入XQuery并不适合所有的情况,如只比较两个xml类型字段的某个节点的值,使用单独的XQuery要比将XQuery嵌入到SQL中更高效。如面的SQL比较table1的xml_data和table3表的id属性值,并返回row节点的数据。

SELECT XMLQUERY('$xd/table1/row' passing t1 as "xd") FROM table1 t1, table3 t3 WHERE XMLEXISTS('$xd/table1[@id=$md/table3/id] ' passing t1.xml_data as "xd", t3.mydata as "md");
    在上面的查询的WHERE子句中,我们向XMLEXISTS中传递XQuery,并在XQuery中设置了连接条件,这看起来有些复杂。其实要完成这些工作,使用普通的XQuery会更简单和便捷。


    五、使用XQuery查询数据库
    XQuery本来是为查询XML数据而制定的标准。但在DB2中,XQuery已经成为专门查询xml类型字段内容的工具。由于XML数据和关系型 数据有着很大的差异,因此,我们需要一种专门的语言来查询这些层次型数据。但XQuery是专门为XML数据而设计的,因此,单独使用XQuery,并不能很好地处理关系型数据。因此,在DB2 Express-C中可以在XQuery中嵌入SQL语言来同时查询XML数据和关系型数据。

    IBM还特意为此提供了编程接口API,用于其他编程语言来使用嵌入SQL的XQuery。这些接口主要包括CLI/ODBC、嵌入式 SQL、JDBC 和 .NET等。DB2命令行也可以支持XQuery,但必须使用XQUERY关键字来启动运行它们。如下面的XQuery语句:
XQUERY FOR $table1 in db2-fn:xmlcolumn("table1.xml_data")/table1 WHERE $table1/@id="xyz" RETURN $table1/row/field1;
     上面的XQuery返回了table1表中xml_data字段的id值为"xyz:"的所有的field1节点值。

    我们也可以在嵌入SQL的XQuery语句中使用全文检索功能。在XQuery中使用全文检索可以在WHERE子句中使用文本搜索函数“CONTAINS"来查找文本。如下面的XQuery语句在table1的xml_data字段中查找description节点值包含”销售信息“的记录,并返回field2结点的值。

XQUERY FOR $emp IN db2-fn:sqlquery(" SELECT xml_data FROM table1 WHERE CONTAINS(xml_data, 'SECTION(""/table1/description"") ""销售信息"" ')=1 ")//row return $emp/field2;
    嵌入了 SQL 的 XQuery 对于那些需要整合关系型数据和 XML 数据的应用程序非常有用。我们可以通过组合方式查询 XML 数据与关系型数据。这同样适用于 SQL/XML。但你可能会发现,在 SQL/XML 中利用 XMLEXISTS 函数连接 XML 值和关系值更轻松。请看下面两条查询语句的效果是一样的,但第二种更简单一些:

    XQuery中嵌入SQL语句
XQUERY FOR $m in db2-fn:sqlquery('SELECT XMLCAST(t2.name as XML) from table2 t2') FOR $d in db2-fn:xmlcolumn("table1.xml_data")/table1 WHERE $d/row/field1 = $m return $d/data(@id);
    在SQL语句中嵌入XQuery
SELECT XMLQUERY('$d/table1/data(@id)' passing t1.xml_data as "xd") FROM table1 t1, table2 t2 WHERE XMLEXISTS('$xd//row[field1 = $n]' passing t1.xml_data as "xd", t2.name as "n");
    虽然嵌入SQL的XQuery可以很好地处理XML数据,但目前还不能在嵌入式 SQL 语句中使用参数标记,因此不允许向XQuery中的SQL传递参数,所以在结合XML数据和关系型数据方面,嵌入XQuery的SQL语言更强大。如嵌入了 SQL 的 XQuery 无法像 SQL/XML 那样用于表示关系列和 XML 列之间的连接。

    六、结束语

    DB2 Express-C为查询XML数据提供了一套强大的Pure XML技术,你可以根据自己的需要选择使用上述的任何一种技术来处理数据。在这几种解决方案中,SQL/XML(在SQL中嵌入XQuery语句)是最灵活的方式,但要是只处理XML数据,建议直接使用XQuery来查询数据表。您还可以利用本文所讨论的技术编写出更为复杂的语句,如在XQuery语句中嵌入含有XQuery语句的SQL。也可以将它们反过来处理,这有些象嵌套的SQL语句。
0
相关文章