本文描述 IBM® DB2® V9.5 版针对 Linux、Unix 和 Windows 的 pureXML™ 增强和新特性。DB2 Version 9 支持将 XML 作为原生数据类型,也支持 SQL/XML、XQuery 语言,以及其他诸如模式支持、发布函数、对实用工具的 XML 支持、分解等特性。DB2 V9.5 增强了其中的一些特性并引入了新特性,以更加高效地处理 XML。本文从如何使 XML 处理更高效和更易于使用的角度解释了这些增强和新特性。
DB2 9 XML 支持概述
DB2 9 引入了原生 XML 数据类型。它将 XML 存储为一种经过解析的分层(原生)格式,并允许用户使用 XQuery 和 SQL/XML 语言查询数据。DB2 XQuery 表达式将存储在 DB2 数据库中的 XML 文档用作 XML 的查询源。函数 xmlcolumn 和 sqlquery 用来连接存储在数据库中的 XML 值,并为 XQuery 解析器提供 XML 序列。
除了 XQuery 语言,DB2 9 还提供了 SQL/XML 函数在单个查询中同时处理 XML 数据和关系数据。SQL/XML 函数 xmlquery、xmltable 和 xmlexists 有助于将 XQuery 嵌入到 SQL 语句中。
DB2 9 还支持模式验证。它引入了新的命令和存储过程,用于将模式注册到数据库并充当数据库对象。在插入操作之前或之后,可以用 xmlvalidate 函数根据已注册的模式验证 XML 值。也可以对模式进行注释,以便于将 XML 数据分解为关系表。 诸如 xmlelement、xmlattributes 等发布函数可用来将关系值转换为 XML 文档。DB2 9 也针对 XML 数据支持对一些实用工具(导入、导出等等)进行了更新。更多关于 Version 9 中的 XML 支持请参见 参考资料 部分。
DB2 V9.5 的新特性
在处理 XML 数据方面,现有的 DB2 9 功能非常强大。DB2 V9.5 增强了一些现有特性并引入了其他功能,以使 XML 处理更加强大和高效。下面是本文将要讨论的功能列表:
◆支持在非 Unicode 数据库中使用 XML
◆子文档更新
◆基础表存储/压缩
◆兼容的 XML 模式演化
◆验证触发器
◆验证检查约束
◆XML 复制
◆XML 联合
◆XML 载入
◆sqlquery() 参数
◆用户友好的发布函数
◆SQL/XML 函数的默认参数传递
◆XSLT 函数
◆XML 分解增强
◆XML 索引增强
◆索引顾问程序(Index advisor)和优化器增强
◆DB2 Data Web 服务
以下小节的大多数代码示例都基于 DB2 V9.5 示例数据库。可以从 DB2 V9.5 命令行处理器运行 db2sampl 命令来创建示例数据库。也可以通过 first step 来创建。first step 是 DB2 提供的一个工具,在安装了 DB2 之后就会执行,也可以在以后通过在 Windows 中选择 Start > All Programs > IBM DB2 > db2 copy name > Set up tools > first steps 来执行。
支持在非 Unicode 数据库中使用 XML
DB2 9 只允许用户使用 UTF-8 代码页创建包含 XML 数据的数据库。这意味着,即使 XML 文档中的值是 ASCII 格式的,也需要存储到 UTF-8 格式的数据库中。DB2 V9.5 去掉了这个限制,并且允许用户用任意代码集创建包含 XML 列的数据库。由于去掉了这个限制,即使数据库不是用 UTF-8 格式创建的,用户也可以更改一个表以添加 XML 列,或者创建一个包含 XML 列的新表。
以下代码创建了一个示例数据库和包含一个 XML 列的示例表:
清单1. 使用默认代码页的数据库
db2 CREATE DATABASE sampledb
db2 CONNECT TO sampledb
db2 CREATE TABLE record(id INT, record XML)
子文档更新
DB2 V9.5 允许用户更新存储在数据库中的 XML 文档的一部分。它引入了 XQuery transform 表达式,该表达式使用 4 个更新表达式 —— insert、delete、replace 和 rename 来修改 XML 文档片段。transform 表达式是 XQuery 语言的一部分,因此可以用在 XQuery 表达式中。对于 DB2 V9.5,一个 transform 表达式中只能使用一个更新表达式。一个 transform 表达式有以下子句:
◆COPY:transform 表达式的 copy 子句 将源 XML 值绑定到一个变量。更新表达式将会在查询中对该副本进行处理。
◆MODIFY:modify 子句 根据更新表达式修改复制的 XML 值。在 MODIFY 子句中可以使用多个更新表达式。
◆return:return 子句 返回修改后的值。
下面将解释这 4 个更新表达式:
1.insert 表达式 将一个新的 XML 节点插入到现有 XML 文档中。可以在 XML 文档指定插入的位置。
2.replace 表达式 用来更新特定节点的特定值。
3.delete 表达式 用来从 XML 文档删除特定节点。
4.rename 表达式 用来对节点进行重命名。
由于 transform 表达式是 XQuery 语言的一部分,因此可以在包含 xmlquery 函数的 SQL 语句中使用它,也可以用于更新语句来更新 XML 值。
清单 2 中的代码更新了示例数据库中 customer 表的 info 列。它更新 XML 文档以使用 cid 关系列的值匹配 CID 属性。
清单2.更新表的 transform 表达式
UPDATE CUSTOMER
SET info =
XMLQUERY('transform
copy $po := $INFO
modify
do replace value of $po/customerinfo/@Cid with $CID
return $po'
passing info as "INFO", cid as "CID")
WHERE cid=1000
如果在表的 XML 列上存在 XML 验证检查约束,在手动更新或者通过触发器更新之前,用户可能需要验证新的 XML 值。
以下代码示例从 purchaseorder 表中删除一个条目,并将修改后的文档作为查询结果。
清单3. transform 表达式
xquery
transform
copy
$po := db2-fn:sqlquery(‘select porder from purchaseorder where
custid = 1002 and orderdate=“2006-02-18”’)
modify
do delete $po/ PurchaseOrder/item[partid = “100-201-01”]
return $po
示例 xupdate.db2 给出了 transform 表达式的不同例子。可以在 sqllib/samples/xml/xquery/clp 目录下找到此示例。
基础表行存储/压缩
在 DB2 9 中,XML 数据和关系数据存储在不同的位置。这个存储位置称作 XML 数据区域(XML data area,XDA)。DB2 9 将所有 XML 文档存储在这个存储位置,这意味着访问 XML 值和关系数据需要更多 I/O。如果 XML 文档较小,而且在存储关系值之后页面大小仍足够容纳 XML 值,那么将 XML 存储在相同的页面能够提供不错的性能收益。这些收益包括:
压缩:因为 XML 数据和关系数据存储在一起,因此可以使用 DB2 9 中引入的压缩技术对 XML 数据进行压缩。由于 XML 值比关系数据大,所以可以获得较高程度的压缩。
查询性能:由于 XML 数据和关系数据存储在相同位置,因此直接插入 XML 数据使得基础表比一般情况下要大。如果 XML 数据的访问频率与表中的其他关系值相当,那么这将提高查询数据的性能。
DB2 V9.5 引入了 XML 数据的基础表行存储。这意味着如果每行的关系数据和 XML 数据的总大小没有超过 1 页面的大小,这两种数据就可以存储在相同的物理页面。只有当一个记录的总大小没有超过页面大小时,才能够对 XML 数据进行基础表行存储。如果是这样,XML 数据就会像通常一样存储在 XML 存储位置。DB2 中允许的页面最大值为 32 KB,因此一个 XML 值的最大插入长度也被限制到 32 KB。如果文档的内部树表示的大小比指定的插入长度小,它们将会被插入。清单 4 中的代码所创建的表可以对 XML 数据进行基础表行存储:
清单4.XML 数据的基础表存储
db2 CREATE TABLE emp1(id INT, info XML INLINE LENGTH 1024)
使用 INLINE 选项指定将 XML 数据跟关系数据存储在一起。这对于要获取的数据都位于相同位置的查询来说很有利。另一方面,对于访问非 XML 数据的查询,这可能导致需要更多的 I/O 才能找到关系数据。
使用 XML 数据基础表行存储的理想情形是,当表只有一个 XML 类型列并且 XML 文档的最大值没有超过页面大小时。
兼容的 XML 模式演化
为了增加灵活性并提供更好的模式演化,DB2 V9.5 为 XML 模式引入了 update 特性。以前注册的模式能够更新为新模式,只要它们互相兼容。如果使用旧模式验证的 XML 文档对于新模式仍然有效,那么这两种模式就是兼容的。
例如,新模式中添加的可选元素和旧模式中的元素兼容,这是由于新元素的可选特性使经过旧模式验证的 XML 文档仍然有效。新 XML 文档可以拥有这个可选元素,并且能够通过新模式的验证。因为旧文档仍然有效,所以更新模式之后无需再执行任何操作。如果模式不兼容,模式更新就会失败。旧模式的注释和标识符仍然会保留。
为了更新模式,DB2 V9.5 引入了 XSR_UPDATE 存储过程。存储过程检查兼容性,只当新模式具备兼容性时才更新模式。要更新模式,用户需要分别注册新旧模式,然后调用 XSR_UPDATE 存储过程。一旦旧模式经过更新,用户可以选择保留旧模式或者将其删除。
让我们以 customer 表的 info 列作为一个例子。info 列包含 addr 元素,该元素具有以下定义(在 sqllib/samples/db2sampl 目录下可以找到完整的模式)。
清单 5. 旧 XML 模式定义
<xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema"
name="addr" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="street" type="xs:string" minOccurs="1" />
<xs:element name="city" type="xs:string" minOccurs="1" />
<xs:element name="prov-state" type="xs:string" minOccurs="1" />
<xs:element name="pcode-zip" type="xs:string" minOccurs="1" />
</xs:sequence>
<xs:attribute name="country" type="xs:string" />
</xs:complexType>
</xs:element>
之后,用户希望拥有一个可选的 HouseNo 元素。要更新已注册的模式以使标识符保持不变,需要先注册包含附加元素的新模式。 新 addr 元素的定义如下:
清单 6. 新 XML 模式定义
<xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema"
name="addr" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="HouseNo" type="xs:string" minOccurs="0" />
<xs:element name="street" type="xs:string" minOccurs="1" />
<xs:element name="city" type="xs:string" minOccurs="1" />
<xs:element name="prov-state" type="xs:string" minOccurs="1" />
<xs:element name="pcode-zip" type="xs:string" minOccurs="1" />
</xs:sequence>
<xs:attribute name="country" type="xs:string" />
</xs:complexType>
</xs:element>
注册之后,可以用以下存储过程将现有模式更新为新模式:
清单7. 使用 XSR_UPDATE 更新模式
db2 call XSR_UPDATE('RSCHEMA','CUSTOMER','RSCHEMA','CUSTOMER1',0)
最后一个参数值 0 表示更新之后不应该删除新模式。如果该参数设置为其他非零值,在更新操作之后新模式将会被删除。
示例代码 xsupdate.db2 演示了兼容的 XML 模式演化。可以在 sqllib/samples/xml/clp 目录中找到该示例。
验证触发器支持
为了提高应用程序灵活性并为用户提供对引入的 XML 文档的自动验证功能,DB2 V9.5 扩展了在 before trigger 中对 XML 的支持。 before trigger 是使用 BEFORE 选项创建的触发器,并在 inster/update/delete 操作之前执行。在 before trigger 中,可以在新变量中引用 XML 值。触发器的操作可以对新值应用 xmlvalidate 函数。触发器的 WHEN 子句可以用来检查是否根据任何指定模式对新值进行了验证。可以使用 WHEN 条件中的 IS VALIDATED 或 IS NOT VALIDATED ACCORDING TO XMLSCHEMA 子句来完成该操作。根据 WHEN 条件的输出,可能还需要验证 XML 值或设置一个新值。目前,只允许将 xmlvalidate 函数用于 XML 类型的 transition 变量。触发器创建之后,在每次执行插入操作时,将会被自动激活并执行,如果在插入语句中没有验证 XML 值,也可以用触发器进行验证。
以下代码是一个 DDL 语句,用于创建 customer 表和根据该表定义的触发器。 只要存在对表的插入操作,就会激活触发器。如果没有在插入语句中对 XML 文档进行验证,触发器将会在插入之前使用 xmlvalidate 函数验证该文档。以下的示例代码假设表的 customer 不存在,并且已经在数据库中注册了该 customer 模式。
清单8. 为一个表定义的触发器
CREATE TABLE Customer ( Cid BIGINT NOT NULL,
info XML,
History XML,
CONSTRAINT PK_CUSTOMER PRIMARY KEY (Cid))
CREATE TRIGGER Trigger_customer NO CASCADE BEFORE INSERT ON customer
REFERENCING NEW AS n
FOR EACH ROW MODE db2sql
WHEN (n.info IS NOT VALIDATED ACCORDING TO XMLSCHEMA ID customer)
BEGIN ATOMIC
SET n.info = XMLVALIDATE(n.info ACCORDING TO XMLSCHEMA ID customer);
END@
示例 xmltrig.db2 提供了不同的场景和操作,这些操作用来分配新值并验证 XML 值,可以在触发器内部执行。该示例可以在 sqllib/samples/xml/clp 目录中找到。
XML 验证检查约束
检查约束(check constraint)是一类可以在创建表时作用到表列的约束。只有当约束合法时,DB2 才允许插入操作,否则插入将会失败。
DB2 V9.5 支持对 XML 值进行检查约束。用户可以使用检查约束来加强对 XML 列的验证。与 before trigger 类似,可以在检查约束中使用 IS VALIDATED ACCORDING TO XMLSCHEMA 子句来加强验证。惟一的区别在于,这种约束只检查验证条件,并不会进行实际的验证。用户可以在插入语句中使用 xmlvalidate 来显式验证 XML 值,或者使用 before trigger 来执行自动验证。根据检查约束中指定的模式,只有当 XML 值有效时,才能成功插入。
对一个表 XML 值应用 before trigger 和检查约束,往往可以确保 XML 值对于指定模式是有效的。只要执行了插入操作,before trigger 就会自动进行验证,而检查约束将会让用户显式地使用 xmlvalidate 函数。这两种方法可以一起使用,以加强 XML 值的完整性。
清单9 中的代码将会修改 清单 8 中创建的表 customer,以对表执行检查约束:
清单9. 检查约束
db2 ALTER TABLE customer ADD CONSTRAINT check_info
CHECK(info IS VALIDATED ACCORDING TO XMLSCHEMA ID customer)
上面创建的检查约束总是会检查是否根据 customer 模式对文档进行了验证。如果没有触发器,用户需要使用 xmlvalidate 函数显式地验证该文档。
示例代码 xmlcheckconstraint.db2 演示了如何为具有相同结构的不同表创建视图,该视图可以进行检查约束,以及按模式对表进行划分。
XML 复制支持
DB2 V9.5 支持将 XML 数据复制到其他支持 XML 数据的数据库。可以使用 WebSphere® Replication Server 9.5 版或者 WebSphere Data Event Publisher 9.5 版来进行复制。WebSphere Replication Server 可以将 XML 数据复制到支持 XML 数据类型的联合目标,也可以将 XML 数据映射到 CLOB/BLOB 列。
像任何其他关系列一样,对 XML 数据的复制是在事务消息中完成的,因此复制的 XML 的大小将受到最大事务消息长度的限制。如果数据很大,可以在原始文档中插入一个占位符文档。也可以在例外表中插入一个例外。
当进行复制时,不能对 XML 模式注册进行复制。此外,在复制过程中也不能对 XML 数据进行验证。
XML 联合支持
WebSphere Federation Server Version 9.1 支持 pureXML,因此能够集成本地和远程的 XML 存储数据。可以将来自不同数据库的 XML 数据当作本地数据查看,而且可以用 DB2 XQuery 和 SQL/XML 查询这些数据。可以在远程联合数据库上创建一个视图,以连续字符串的方式查看该数据,这些数据可以在 WebSphere Federation Server 上解析为 XML 值。现在 DB2 可以使用 SQL/XML 和 XQuery 语言通过为视图创建的别名来查询数据。
与验证本地 XML 值的方式相同,可以使用 db2 xmlvalidate 函数验证来自不同联合数据源的 XML 数据。
载入支持
DB2 9 主要支持两种用 XML 值填充表的方式。insert 语句向表中插入 XML 值,import 实用程序用于将大量数据导入表中。
DB2 V9.5 扩展了对 load 实用程序的支持。load 支持 import 支持的大多数 XML 数据选项。可以使用 FROM 子句为 XML 数据指定路径。在 load 期间可以使用 XMLVALIDATE USING 子句对 XML 数据进行验证。load 有 3 个不同的选项:XDS、SCHEMA 和 SCHEMALOCATION HINTS。当指定 XDS 选项时,可以使用 DEFAULT, IGNORE 和 MAP 子句。这些选项的含义与 import 中对应选项的含义相同。可以使用文件类型修改器 XMLCHAR 和 XMLGRAPHIC 指定数据的代码页。XML 数据指定程序(XML data specifier,XDS)在数据文件中指定 XML 值。load 重启的行为和原来一样。它通过扫描所有 XML 文档重新构建所有索引。
示例代码 xmlload.db2 演示了 DB2 V9.5 中可用的 XML 数据载入选项。可以在 sqllib/samples/xml/clp 目录中找到该示例。
XSLT 支持
DB2 V9.5 提供了使用数据库本身的 XSL 转换来处理 XML 文档的功能。可以使用 XSLT 样式表将存储在数据库中的 XML 文档转换为 HTML 格式。为此,DB2 V9.5 引入了 xsltransform 函数。该函数还支持使用参数的样式表。xsltransform 函数可以将作为 XML 文档存储在数据库表列中的 XSLT 样式表应用到 XML 文档上。这为用户提供了灵活性,用户可以检索来自数据库的经过转换的 XML 文档,并可以直接在 Web 上显示。
现在,假设您已有下面的 XML 文档:
清单10. XML 文档
Ice Scraper, Windshield 4 inch
Basic Ice Scraper 4 inches wide, foam handle
3.99
以及相应的 XSLT 样式表:
清单11. XSLT 样式表
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="products">
<html>
<head/>
<body>
<table border="1">
<th>
<tr>
<td width="80">product ID</td>
<td width="200">product name</td>
<td width="200">price</td>
<td width="50">details</td>
</tr>
</th>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="product">
<tr>
<td><xsl:value-of select="@pid"/></td>
<td>><xsl:value-of select="./description/name"/></td>
<td><xsl:value-of select="./description/price"/></td>
<td><xsl:value-of select="./description/details"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
这些文档需要存储在表中,或者当作参数传递。当将这些值作为参数传递时,请确保它们是格式良好的 XML 文档。参数的数据类型可以是 XML、VARCHAR、CLOB 或 BLOB。假设文档和样式表都存储在表中,可以用以下语句转换 XML 文档:
注意:示例假设存储文档的表名称为 xslt,XML 文档的列名为 xmldoc,XSL 文档的列名为 xsldoc。
清单12. XSLTransform 表达式
SELECT XSLTRANSFORM (description USING stylesheet AS CLOB (10M))
FROM product_details
这个查询输出一个 HTML 文档,可以在浏览器中进行查看。清单 13 显示该 HTML 输出:
清单13. XSLTransform 表达式的 HTML 输出
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<table border="1">
<th>
<tr>
<td width="80">product ID>td>
<td width="200">product name>/td>
<td width="200">price>/td>
<td width="50">details>/td>
</tr>
</th>
<tr>
<td>100-201-01>/td>
<td>Ice Scraper, Windshield 4 inch>/td>
<td>3.99>/td>
<td>Basic Ice Scraper 4 inches wide, foam handle>/td>
</tr>
</table>
</body>
</html>
用户也可以将 XML 文档和一个 XSLT 样式表存储在不同的表中,而且可以通过连接表将单个 XSLT 样式表应用到多个 XML 值。
发布函数
发布函数用来将关系数据转换为 XML 值。DB2 9 引入了 SQL/XML 支持,该支持在 DB2 V9.5 中得到了增强和简化。一些 DB2 9 SQL/XML 函数,比如 xmlelement,需要提供所有 XML 元素的名称、属性和其他节点,而这些元素来自表的关系列或者被显式地提供。有时用户需要生成 XML 值,但是不想牵涉到元素名称。
通过引入新函数 xmlrow 和 xmlgroup,DB2 V9.5 对现有的发布函数进行了扩展。这些函数从表列获得 XML 元素的名称和值。xmlrow 输出是一个表示为 XML 的行值的序列,xmlgroup 函数将所有值集合到一个根节点下。
下表是一个示例 employee 表,该表拥有员工的详细地址,包含以下记录:
ID NAME STREET CITY STATE COUNTRY
1 manoj sector14 gurgaon haryana india
下面的查询在该行中应用了 xmlrow 和 xmlgroup 函数。
清单14. 新发布函数
db2 SELECT XMLROW(id, name, street, city,state, country) FROM EMPLOYEE
1
manoj
sector14
gurgaon
haryana
india
db2 SELECT XMLGROUP(id, name, street, city,state, country) FROM EMPLOYEE
1
manoj
sector14
gurgaon
haryana
india
在 DB2 9 中,为了得到相同结果,除了显式地提供元素名称,还需要将 xmlelement 应用到每个列值。
跟 V91 版本中相同的查询相比,示例代码 xmlintegrate.db2 为这些函数提供了更多复杂例子。可以在 sqllib/samples/xml/clp 目录下找到该示例。
将参数传递给 sqlquery 函数
在 DB2 9 中,sqlquery 函数将一个 SQL 语句嵌入到 XQuery 表达式中。此函数将一个字符串值作为输入,该字符串是一个有效的 SQL 全选择语句。在 DB2 9 中,不能将参数从 XQuery 语句传递给此函数。
DB2 V9.5 增强了该函数,引进了一个新的 parameter 函数,该函数将一个整数值作为输入。现在,sqlquery 函数可以将多个参数作为输入,第一个参数是一个表示全选择的字符串,其后是参数的值。sqlquery 函数的第一个字符串参数可以包含 parameter 函数,该函数将会被传递给 sqlquery 函数的参数取代,该参数位于第一个必需的字符串参数之后。传递给 parameter 函数的整数值表示在调用 sqlquery 函数中参数的位置,该参数将会在调用中被取代。 例如,parameter(1) 告诉解析器用字符串参数后的第一个参数替代这个值。参数的类型应该和全选择所期望的值类型相同。可以使用类型转换函数将值转换为一个合适的类型。
让我们以示例数据库中的 customer 表作为例子。可以通过运行 db2sampl 命令和从 first step 创建示例数据库。first step 是 DB2 提供的一个工具,在安装了 DB2 之后就会执行,也可以在以后通过在 Windows 中选择 Start> All Programs > IBM DB2 > db2 copy name > Set up tools > first steps 来执行。
customer 表包含一个作为关系列的 cid 列,以及表示顾客 id 的键值。info XML 列具有一个属性 Cid,该属性也表示顾客 id。如果数据是一致的,那么属性 Cid 值应该与特定行的 cid 列值相同。以下的查询将检查数据保持一致的行的数量。Cid 属性的值被传递给 sqlquery 函数,以将其与关系 cid 值进行比较。
清单15. 将参数传递给sqlquery函数
xquery declare default element namespace "http://posample.org";
for $i in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo/@Cid
for $j in db2-fn:sqlquery("select info from customer where cid=parameter(1)", $i)
return
{$i}
此查询返回所有数据一致的顾客 id。
示例代码 xqueryparam.db2 提供了一些不错的例子,将一个和多个参数传递给 sqlquery 函数。可以在 sqllib/samples/xml/clp 目录中找到该示例。
现有函数 XMLQuery、XMLtable 和 XMLExists 的默认传递行为
在 DB2 9 中,函数 xmlquery、xmltable 和 xmlexists 用来将 Xquery 语句嵌入到 SQL 语句中。利用这些函数的 PASSING 子句将参数从 SQL 语句传递给这些函数。
在 DB2 9 中,如果同一个 SQL 语句中的这些函数会执行多次,那么每次执行都需要一个独立的 PASSING 子句。有时这会使查询的结构看起来很复杂和庞大。DB2 V9.5 扩展了这些函数,以使用默认的传递机制。现在,将一个列名称用作这些函数的 Xquery 中的一个变量名。如果没有使用显式的 PASSING 子句,默认情况下 DB2 将传递相同列给一个变量。这使查询更精简并更易于理解。以下代码给出了一个针对示例数据库表的例子。查询为名为 Robert Shoemaker 的顾客获取 purchaseorder 中的第一项。
清单 16. SQL/XML 函数的默认传递行为
SELECT XMLQUERY('declare default element namespace "http://posample.org";
$PORDER/PurchaseOrder/item[1]' )
FROM purchaseorder AS p, customer AS c
WHERE XMLEXISTS('declare default element namespace "http://posample.org";
$INFO/customerinfo[name="Robert Shoemaker" and @Cid = $CUSTID]')
对于 SELECT 子句中的 xmlquery 函数,默认情况下传递 purchaseorder 表的 porder 列。同样地,对于 xmlexists 函数,默认情况下传递 customer 表的 info 列和 custid 列。请确保以大写字母的方式使用这些变量的名称,因为 xquery 是一个区分大小写的语言,而且关系列名称常常以大写的方式存储。
XML 验证约束
DB2 V9.5 增强了 SELCT 语句使用的 IS VALIDATED 子句,以包含 ACCORDING TO XML SCHEMA ID。现在用户能够提供多个模式并仅选择针对这些模式验证的 XML 值。DB2 V9.5 可以将任何 XML 表达式(而不是一列)作为一个操作数,这具有很大的灵活性。下面的例子只选择了 customer 表中用 customer 模式验证之后的文档。
清单17. SELECT 语句中的 XML 验证约束
db2 SELECT info FROM customer
WHERE info IS VALIDATED ACCORDING TO XMLSCHEMA ID customer
经过注释的 XML 模式分解
DB2 9 支持 XML 模式的注释,因此除递归模式外,可以将数据分解为关系表。DB2 V9.5 解除了这个限制,现在即使模式是递归的,用户也可以对数据进行注释和分解。
DB2 V9.5 扩展了分解,以提供插入顺序。当将数据分解成多个具有外键关系的表时,这尤其重要。在这种情况下,应该首先填充主表,以保持引用约束。可以使用以下注释指定插入顺序:
清单18. 对模式进行注释,以提供插入顺序
CUSTOMER
PURCHASEORDER
示例代码 recxmldecomp.db2 和 xmldecomposition.db2 给出了一些不错的例子,其中分别演示了将递归模式和插入顺序进行注释并分解到表中。可以在 sqllib/samples/xml/clp 目录中找到示例代码。
XML索引增强
DB2 9 引入了 XML 索引。可以在数据库中 XML 文档的特定节点上创建 XML 索引。索引的数据类型可以是 VARCHAR、DOUBLE、DATE 或 TIMESTAMP。如果索引的数据类型与 XML 文档的元素类型不匹配,DB2 将插入 XML 值,但是不会为该值创建索引。
DB2 V9.5 为索引引入了一个附加子句 REJECT INVALID VALUES。如果使用该子句创建索引,并且索引的数据类型与正在插入的 XML 文档中元素的数据类型不匹配,插入将会失败。如果在插入 XML 值之后创建索引,而且数据类型不匹配,索引创建也会失败。
对于 DB2 V 9.5,这种行为是默认的,也可以使用 IGNORE INVALID VALUES 子句显式地指定这种行为。
下面的示例将会使用 REJECT INVALID VALUES 为 customer 表的 Cid 属性创建一个索引。
清单19. XML 索引
db2 CREATE INDEX index1 ON customer(info)
GENERATE KEY USING XMLPATTERN
'declare default element namespace "http://posample.org";
/customerinfo/@cid' as SQL DOUBLE REJECT INVALID VALUES
Index顾问程序和优化器增强
索引顾问程序可以用来获得关于同时为 XML 和关系数据建立索引的建议。通过同时为 XML 和关系数据建立索引,用户可以获得良好的性能提升。DB2 9.5 优化器使用两种类型的索引来优化查询,并帮助选择最佳的查询执行计划。
DB2 Data Web 服务
使用 Data Web 服务,可以将 DB2 V9.5 XML 数据作为 数据库 manipulation(ML)操作的 Web 服务公开。Data Web 服务(DES)将 ML 操作(如插入、更新、选择和存储过程)作为 Web 服务公开。可以通过 Web 浏览器、用户客户端使用基于 HTTP 的 SOAP 协议(例如 POST 和 GET 方法)来访问这些 Web 服务。通过在现有数据库工具中集成基于 Eclipse 的工具,可以对 Data Web 服务提供支持。
控制中心也经过了更新,以处理 XML 数据。
结束语
DB2 9 将 XML 作为一个新数据类型引入,而且提供了处理 XML 值的基础设施。它提供了一些基本功能,比如查询 XML 文档、注册模式和验证 XML 文档、使用 SQL/XML 在 SQL 和 XQuery 之间交互。DB2 V9.5 增强了现有的功能,并提供了更多函数以有效地处理 XML 数据。