使用XQuery查询DB2 XML数据(一)

日期: 2007-12-09 来源:TechTarget中国

  关于 XQuery

  XQuery 在很多关键方面都与 SQL 有所不同,这很大程度上是因为这两种语言是针对两种具有不同特征的数据模型而设计的。XML 文档包含层次结构,并且有其固有的顺序。

  而基于 SQL 的数据库管理系统所支持的表格数据结构是平面的(flat),并且是基于集合的;因此,行之间不存在顺序。

  这两种数据模型的不同导致它们各自的查询语言有很多基本的不同。例如,XQuery 支持路径表达式,以允许程序员在 XML 的层次结构中导航,而纯 SQL(没有 XML 扩展)则不支持。XQuery 支持有类型的和无类型的数据,而 SQL 数据总是以指定类型定义的。XQuery 没有 null 值,因为 XML 文档会忽略缺失的或未知的数据。当然,SQL 使用 null 来表示缺失的或未知的数据值。XQuery 返回一系列的 XML 数据,而 SQL 则返回各种 SQL 数据类型的结果集。

  这只是 XQuery 和 SQL 之间的基本不同点中的一部分。提供一份详尽的列表超出了本文的范围,不过即将发表的 IBM Systems Journal 将更详细地讨论这些语言的不同。现在我们就探索一下 XQuery 语言的一些基本方面,并看看如何使用它来查询 DB2Viper 中的 XML 数据。

  样本数据库

  本文中的查询访问在 “DB2Viper 快速入门”(developerWorks,2006 年 4 月)中创建的样本表。清单 1 给出了样本数据库中 “items” 和 “clients” 表的定义:

  清单 1. 表定义

create table items (

id int primary key not null,

brandname varchar(30),

itemname varchar(30),

sku int,

srp decimal(7,2),

comments xml

)

create table clients(

id int primary key not null,

name varchar(50),

status varchar(10),

contactinfo xml

)

  图 1 中显示了 “items.comments” 列中包含的样本 XML 数据,而 图 2 中则显示了 “clients.contactinfo” 列中包含的样本 XML 数据。随后的例子查询将引用这两个 XML 文档中的一个或两个中的特定元素。

  图 1. 存储在 “items” 表的 “comments” 列中的样本 XML 文档

  图 2. 存储在 “clients” 表的 “contactinfo” 列中的样本 XML 文档

  查询环境

  本文中的所有查询都是通过交互方式发出的。这可以通过 DB2命令行处理器或 DB2Control Center 的 DB2Command Editor 来完成。本文中的屏幕图像和说明主要使用后一种方式。(DB2Viper 还附带了一个基于 Eclipse 的 Developer Workbench,它可以帮助程序员以图形化的方式构造查询。本文不讨论应用程序开发问题和 Developer Workbench。)

  要使用 DB2Command Editor,启动 Control Center,并选择 Tools -> Command Editor。这时将出现如 图 3 所示的窗口。在上面的面板中输入查询,单击左上角的绿色箭头运行该查询,然后可以在下面的面板中或者在 “Query Results” 选项卡中查看输出。

  图 3. DB2Command Editor,可以从 DB2Control Center 中启动

  XQuery 例子

  与在 “用 SQL 查询 DB2XML 数据” 中一样,本文将逐步讲解一些常见的业务场景,并展示如何使用 XQuery 来满足对 XML 数据的请求。本文还探索了需要将 SQL 嵌入在 XQuery 中的更复杂的情景。

  XQuery 提供了一些不同类型的表达式,这些表达式可以随意组合。每个表达式返回一系列的值,这些值又可以作为其他表达式的输入。最外面的表达式的结果就是查询的结果。

  本文主要讨论两种重要的 XQuery 表达式:“FLWOR” 表达式和路径表达式。FLWOR 表达式非常像 SQL 中的 SELECT-FROM-WHERE 表达式 —— 它用于对由多项组成的一个列表进行迭代,并且可以选择返回通过在每一项上进行计算得到的值。而路径表达式则可以在分层的 XML 元素之间进行导航,并返回在路径末端找到的元素。

  与 SQL 中的 SELECT-FROM-WHERE 表达式类似,XQuery FLWOR 表达式可以包含数个以某个关键词开头的子句。在 FLWOR 表达式中,有以下用于作为子句开头的关键字:

  for:对输入序列进行迭代,依次将一个变量绑定到每个输入项

  let:声明一个变量并为之赋值,可能是一个包含多项的列表
 
  where:指定过滤查询结果的标准

  order by:指定结果的排序顺序

  return:定义所返回的结果 XQuery 中的路径表达式由一系列的 “步(step)” 组成,之间以斜杠隔开。在最简单的形式中,每一步在 XML 层次中向下导航,以发现由前一步返回的元素的孩子。路径表达式中的每一步还可以包含一个谓词,用于过滤该步返回的元素,只保留满足某种条件的元素。例如,假设变量 $clients 被绑定到包含 元素的 XML 文档的一个列表,则 4 步路径表达式 $clients/Client/Address[state = "CA"]/zip 将返回居住在加利福尼亚的客户的邮政编码。

  在很多情况下,可以任意使用 FLWOR 表达式或路径表达式编写查询。

  使用 DB2XQuery 作为顶层查询语言

  要在 DB2Viper 中直接执行 XQuery(而不是将它嵌入在 SQL 语句中),必须以关键字 xquery 作为查询的开头。这个关键字将指示 DB2调用它的 XQuery 解析器来处理请求。注意,只有在使用 XQuery 作为最外层(顶层)语言的时候才需要这么做。如果是将 XQuery 表达式嵌入在 SQL 中,则不需要在语句之前加上 xquery 关键字。但是,本文使用 XQuery 作为基本语言,因此所有查询之前都加上 xquery。

  当 XQuery 被作为顶层语言时,它需要一个输入数据的源。XQuery 获得输入数据的一种方式是调用一个名为 db2-fn:xmlcolumn 的函数,调用时带一个参数,表明 DB2表中 XML 列所在的表名和该列的列名。db2-fn:xmlcolumn 函数返回存储在给定列中的一系列的 XML 文档。例如,下面的查询返回一系列包含客户联系方式信息的 XML 文档:

  清单 2. 返回客户联系方式数据的简单 XQuery

  xquery db2-fn:xmlcolumn(‘CLIENTS.CONTACTINFO’)

  您可能还记得,在我们的数据库模式中(参见 “样本数据库” 小节),我们将那些 XML 文档存储在 “clients” 表的 “contactinfo” 列中。注意,这里的列名和表名是大写的。这是因为表名和列名在被写入到 DB2的内部编目之前通常要换成大写形式。由于 XQuery 是大小写敏感的,因此小写的表名和列名不能与 DB2编目中的大写名称相匹配。

  检索特定的 XML 元素

  首先我们来看一个基本的任务。假设您要检索所有提供了有关传真信息的客户的传真号。清单 3 给出了编写该查询的一种方式:

  清单 3. 检索客户传真数据的 FLWOR 表达式

  xquery

  for $y in db2-fn:xmlcolumn(‘CLIENTS.CONTACTINFO’)/Client/fax

  return $y

  第一行指示 DB2调用它的 XQuery 解析器。接下来的一行指示 DB2对包含在 CLIENTS.CONTACTINFO 列中的 Client 元素的 fax 子元素进行迭代。每个 fax 元素被依次与变量 $y 绑定。第三行指出在每次迭代中返回 $y 的值。结果为一系列的 XML 元素,如 清单 4 所示:

  清单 4. 上述查询的示例输出

  4081112222
 
  5559998888

  随便提一下,这里的输出还将包含与本文关系不大的一些信息:XML 版本和编码数据,例如 ,以及 XML 名称空间信息,例如 。为了使输出更简单,本文省略了这些信息。然而,对于很多 XML 应用程序来说这些信息可能很重要。如果使用 DB2命令行处理器来运行查询,那么可以使用 -d 选项来省略 XML 声明信息,还可以使用 -i 选项以一种美观的方式打印结果。

  清单 3 中显示的查询也可以用一种更简单的三步路径表达式来表达,如 清单 5 所示:

  清单 5. 检索客户传真数据的路径表达式

  xquery

  db2-fn:xmlcolumn(‘CLIENTS.CONTACTINFO’)/Client/fax

  路径表达式的第一步调用 db2-fn:xmlcolumn 函数从 CLIENTS 表的 CONTACTINFO 列获得一个 XML 文档的列表。第二步返回这些文档中的所有 Client 元素,第三步则返回嵌入在这些 Client 元素中的 fax 元素。

  如果您无兴趣通过查询获得 XML 片段,而只想要符合条件的 XML 元素值的文本表示,那么可以在 return 子句中调用 text() 函数,如 清单 6 所示:

  清单 6. 两个用于检索客户传真数据的文本表示的查询

  xquery

  for $y in db2-fn:xmlcolumn(‘CLIENTS.CONTACTINFO’)/Client/fax

  return $y/text()

  (or)

  xquery

  db2-fn:xmlcolumn(‘CLIENTS.CONTACTINFO’)/Client/fax/text()

  上述查询的输出如 清单 7 所示:

  清单 7. 上述查询的示例输出

  4081112222

  5559998888

 

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • Google BigQuery使用SQL在云端处理大数据

    Google正在建设在云中分析大数据的服务被称为BigQuery。那么Google BigQuery使用SQL在云端处理大数据的优势在哪里?

  • 如何用XUL进行XQuery语言编写?

    自从和XML数据库合作以来,XQuery获得了巨大的牵引力,但其最薄弱的一环就是写入数据库还有很大局限性。应用程序有时必须创建多种XML数据库或者写回整个图表才能进行简单的数据变化。

  • 超越传统:NoSQL数据库大比拼

    在两三年前,选择数据库是一件非常容易的事。资金充足的企业会选择甲骨文数据库,而预算不足企业则会选择MySQL。不过,如今的情况已经大不相同了。

  • XQuery:数据集成领域的精耕细作者

    XQuery标准的发展历程对我们很有启发意义,TT SOA多年以来对此也有详细描述。XQuery诞生于XML和Web服务的早期,目的是向刚开始使用XML数据……