科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道教你使用SQL查询DB2 9中的XML数据

教你使用SQL查询DB2 9中的XML数据

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

虽然 DB2 的混合体系结构与之前的版本有很大的不同,但是要利用它的新 XML 功能并不难。如果您已经熟悉 SQL,那么很快就可以将这方面的技能转化到对存储在 DB2 中的本地 XML 数据的处理上。

作者:赛迪网 来源:赛迪网 2007年9月5日

关键字: XML 数据库 DB2 DB2 9 SQL

  • 评论
  • 分享微博
  • 分享邮件
 

SQL/XML 查询

顾名思义,SQL/XML 被设计用来为 SQL 和 XML 两者之间搭一座桥。它首先是 SQL 标准的一部分,经过演化现在包括将 XQuery 或 XPath 表达式嵌入 SQL 语句的规范。XPath 是用于导航 XML 文档以便发现元素或属性的一种语言。XQuery 包括对 XPath 的支持。

请务必注意,XQuery(和 XPath)表达式是大小写敏感的。例如,引用 XML 元素 "zip" 的 XQuery 并不适用于名为 "ZIP" 或 "Zip" 的 XML 元素。SQL 程序员有时候很难记住大小写敏感这一点,因为 SQL 查询语法允许使用 "zip"、"ZIP" 和 "Zip" 来引用同一个列名。

DB2 Viper 提供了超过 15 个 SQL/XML 函数,通过这些函数可以搜索 XML 文档中的特定数据,将传统数据转换成 XML,将 XML 数据转换成关系数据,以及执行其他有用的任务。本文不讨论 SQL/XML 的所有方面,而只是谈到几种常见的查询挑战,以及一些关键的 SQL/XML 函数如何解决这些挑战。

根据 XML 元素值 “限制” 结果

SQL 程序员常常编写根据某种条件限制从 DBMS 返回的行的查询。例如,清单 3 中的 SQL 查询限制从 "clients" 表中检索的行,使之只包括那些具有 "Gold" 状态的客户。在这个例子中,客户的状态可在 SQL VARCHAR 列中捕捉。但是,如果您想根据某种应用于 XML 列中数据的条件对搜索进行限制,那么应该怎么做呢?SQL/XML 的 XMLExists 函数为完成该任务提供了一种手段。

通过 XMLExists 可以在 XML 文档中找到一个元素,并测试它是否满足某个特定的条件。如果用在 WHERE 子句中,则 XMLExists 可以限制返回的结果,使之只包括那些包含具有特定 XML 元素值的 XML 文档的行(换句话说,指定的值等于 "true")。

让我们看看早先遇到的一个查询问题。假如您想找到居住在具有特定邮政编码的地区的所有客户的姓名。您也许还记得,"clients" 表的一个 XML 列中存储了客户的地址(包括邮政编码)。(见 图 2。)通过使用 XMLExists,可以从 XML 列中搜索目标邮政编码,并相应地限制返回的结果集。下面的 SQL/XML 查询返回居住在邮政编码为 95116 的地区的客户的姓名:

清单 5. 根据 XML 元素值限制结果

select name from clientswhere xmlexists('$c/Client/Address[zip="95116"]'
passing clients.contactinfo as "c")

第一行是一个 SQL 子句,指定仅检索 "clients" 表 "name" 列中的信息。WHERE 子句调用 XMLExists 函数,指定一个 XPath 表达式,这个表达式使 DB2 找到 "zip" 元素并检查元素值是否为 95116。"$c/Client/Address" 子句表明 DB2 用于定位 "zip" 元素的 XML 文档层次结构中的路径。通过使用可以从节点 "$c"(稍后将会解释)访问的数据,DB2 将从 "Client" 元素中找到它的子元素 "Address",以便检查邮政编码("zip" 值)。最后一行决定 "$c" 的值:它是 "clients" 表的 "contactinfo" 列。因此,DB2 检查 "contactinfo" 列中的 XML 数据,从根元素 "Client" 深入到 "Address" 子元素再找到 "zip" 子元素,然后判断客户是否居住在目标地区。如果客户住在目标地区,则 XMLExists 函数的返回值为 "true",DB2 将返回与那一行相关的客户的姓名。

在使用 XMLExists 查询谓词时经常会出现一个错误,如 清单 6 所示。

清单 6. 根据 XML 元素值限制结果时采用的不正确语法

select name from clientswhere xmlexists('$c/Client/Address/zip="95116" 
'passing clients.contactinfo as "c")

虽然这个查询也可以成功地执行,但是它不能限制结果,使之仅包含居住在邮政编码为 95116 的地区的客户。(这是由于标准中规定的语义造成的,而且这并不是 DB2 所特有的。)为了限制结果,使之仅包含居住在邮政编码为 95116 的地区的客户,需要使用前面 清单 5 中展示的语法。

您可能很想知道如何在应用程序中包括限制 XML 数据的查询。虽然本文不详细讨论应用开发话题,但还是提供了一个 简单的 Java 例子,这个例子在一条 SQL/XML 语句中使用一个参数标记位将输出限制为居住在给定地区的客户的信息。

“投影” XML 元素值

现在让我们考虑一种稍微有些不同的情景,假设您想将 XML 值投影到返回的结果集。换句话说,我们要从 XML 文档中检索一个或多个元素值。有很多方法可以做这件事。首先我们使用 XMLQuery 函数来检索一个元素的值,然后使用 XMLTable 函数来检索多个元素的值,然后将这些映射到一个 SQL 结果集的列。

我们来考虑如何解决之前摆在我们面前的一个问题:如何创建一个列出 Gold 客户的 email 地址的报告。下面 清单 7 中的查询调用 XMLQuery 函数来完成这项任务:

清单 7. 检索符合条件的客户的 email 信息

select xmlquery('$c/Client/email' passing contactinfo as "c") from clients where status = 'Gold'

第一行指定要返回根元素 "Client" 的 "email" 子元素的值。第二行和第三行表明 DB2 在哪里可以找到该信息 —— 在 "clients" 表的 "contactinfo" 列中。第四行进一步限制查询,表明您只对 Gold 客户的 email 地址感兴趣。这个查询将返回一组 XML 元素和值。例如,如果有 500 名 Gold 客户,每个客户有一个 email 地址,那么输出将是一个单列的结果集,一共有 500 行,如 清单 8 所示:

清单 8. 之前查询的示例输出

1--------------------------------------------<email>user5976@anyprovider.com
</email>. . . <email>someID@yahoo.com</email>

如果每个 Gold 客户有多个 email 地址,那么需要指示 DB2 只返回首要的地址(也就是在客户的 "contactinfo" 文档中找到的第一个 email 地址)。为此,可以修改查询的第一行中的表达式:

清单 9. 检索每个符合条件的客户的第一个 email 地址

select xmlquery('$c/Client/email[1]' passing contactinfo as "c") from clients where status = 'Gold'
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章