ChinaUnix >> 文档中心 >> 数据库技术 >> DB2 >> 正文 IT新闻与评论交流区
 
编写 DB2 pureXML 的 XQuery 和 SQL/XML 查询
发布者:豆豆网  日期: 2010-10-21 00:00:00 浏览次数:0 (共有_条评论) 查看评论 | 我要评论
 

  引言

  本文提供了使用 DB2 pureXML 查询 XML 数据的快速参考。本文回顾了与一些常见查询相关的语法,包括 XQuery with SQL 格式和 SQL/XML with XQuery 格式。甚至是在这两种格式之间选择时,也可以多种方式编写大多数查询,并获得同样的结果。

  本文主要面向熟悉 XML 的软件架构师、设计人员和开发人员。本文假设您正在使用 IBM 开发工具,比如 Rational® Software Architect、Rational Application Developer、Optim® Development Studio 或 InfoSphere™ Data Architect,在 DB2 中处理 XML 数据。

  搭建环境

  首先搭建处理查询的环境。

  访问模板

  本文中每个查询示例的语法都来自 IBM 工具提供的编辑器模板。要访问这些工具的模板集,请完成以下步骤:

  导航到 Window > Preferences。

  在 Preferences 中,导航到 Data Management > SQL Development > SQL and XQuery Editor > Templates,如图 1 所示。

  查看可用的模板,导入由其他产品提供的模板,或者更新模板并将它们导出,与其他人共享。

图 1. SQL 和 XQuery 模板视图
编写 DB2 pureXML 的 XQuery 和 SQL/XML 查询

  查看原图(大图)

  编辑 SQL 或 XQuery 脚本时,在编辑器窗口中按 CTRL+空格 组合键,可访问并使用可用的模板。

  设置数据库表

  本文的示例使用 SAMPLE 数据库,该库中的 XML 数据由 DB2 提供。可以将这些示例安装为 DB2 First Steps 的一部分,如图 2 所示。也可以在安装后在命令行输入 db2sampl -xml。

图 2. 使用 First Steps 配置示例数据
编写 DB2 pureXML 的 XQuery 和 SQL/XML 查询

  查看原图(大图)

  本文的示例查询使用 SAMPLE 数据库的 CUSTOMER 表,如图 3 所示。

图 3. SAMPLE 数据库中 CUSTOMER 表的视图
编写 DB2 pureXML 的 XQuery 和 SQL/XML 查询

  清单 1 显示了一个示例 XML 文档,该文档可在 CUSTOMER 表的 INFO 列中找到。

清单 1. INFO 列

<customerinfo Cid="1001"> 
  <name>Kathy Smith</name> 
  <addr country="Canada"> 
    <street>25 EastCreek</street> 
    <city>Markham</city> 
    <prov-state>Ontario</prov-state> 
    <pcode-zip>N9C 3T6</pcode-zip> 
  </addr> 
  <phone type="work">905-555-7258</phone> 
</customerinfo> 

  使用 XQuery 创建查询

  本节介绍使用 XQuery 如何创建查询。

  XQuery 表达式的类型

  下列列表显示了可在同一查询中使用的一些不同类型的 XQuery 表达式。

  主

  使用语言的基础基元,包括文本、变量引用、括号表达式和函数调用等。

  路径

  使用 XPath 2.0 的语法识别 XML 树中的节点。

  FLWOR

  迭代序列,并将变量绑定到中间结果。

  比较

  比较两个值。

  构造函数

  在查询内部创建 XML 结构。

  逻辑

  使用 and/or 计算布尔型值。

  条件

  使用 if、then 和 else 评估测试表达式的值是 true 还是 false。

  基本查询

  使用 XQuery 在 DB2 中查询 XML 数据有两种基本方法。您可以使用 DB2 sqlquery 函数以使用 SQL 访问具体 XML 数据,或者使用 DB2 xmlcolumn 函数以使用 XQuery 访问列中的所有 XML 数据。清单 2 显示了基本语法。

清单 2. 基本语法

xquery db2-fn:sqlquery(${sql_query})${xquery_expression} 

  清单 3 显示了一个简单的查询,在其中可使用 SQL 返回 INFO 列的文档的子集。在查询的末尾,包含一个从 XML 文档内部检索 name 元素的 XPath 表达式。

清单 3. 返回文档的子集

xquery db2-fn:sqlquery("select INFO from CUSTOMER where CID = 1000")/customerinfo/name 

  在本例中,您对 INFO 列中的所有 XML 文档都感兴趣。对于每个文档,您使用路径表达式返回 name 元素。

  清单 4 显示了 xmlcolumn 语法。

清单 4. XMLcolumn 语法

xquery db2-fn:xmlcolumn('${schema}.${table}.${column}')${xquery_expression} 

  清单 5 展示了 INFO 列中的所有 XML 文档。对于每个文档, 您使用路径表达式返回 name 元素。

清单 5. INFO 列中的 XML 文档

xquery db2-fn:xmlcolumn('CUSTOMER.INFO')/customerinfo/name 

  FLWOR

  使用 XQuery 的常见方法是编写包含下列子句的查询,其中一些子句是可选的:For、Let、 Where、Order by 和 Return。这些简称为 FLWOR(读音为 flower)。 记住,XQuery 希望得到 XML 输出并且返回 XML。语法如清单 6 所示。

清单 6. FLWOR 语法

xquery 
for $$i in ${xquery_expression} 
let $$x := ${xquery_expression} 
where ${xquery_expression} 
order by ${xquery_expression} 
return ${xquery_expression} 

  清单 6 中的语法包括所有可用的 FLWOR 表达式元素。下面是一些示例,这些示例表明您可以使用可选元素修改查询的结构。

  清单 7 是简单 FLOWER 查询的一个示例,为每个 customerinfo 元素检索与每个 address 相关的 city 元素。

清单 7. 简单的 FLWOR

xquery 
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo 
return $c/addr/city 

  清单 8 为上一个查询添加了一个限制,仅为具有属性 Cid = 1001 的 customer 返回 city。

清单 8. 返回 city 的 FLWOR

xquery 
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo 
where $c/@Cid = 1001 
return $c/addr/city 

  清单 9 提取 prov-state 是 Ontario 的客户的名称,并根据 name 的字母顺序排列结果。

清单 9. 查询 Ontario 的 FLWOR

xquery 
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo 
where $c/addr/prov-state = "Ontario" 
order by $c/@name  
return $c/name 

  清单 10 使用 Let 分配变量,保留居住于 Canada 的客户的 pcode-zip 值,然后按照 Cid 的字母顺序排列结果。然后代码构造一个新 XML 元素 <contact>,该元素包括 Cid 和 pcode-zip。

清单 10. 查询 pcode-zip 的 FLWOR

xquery 
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo 
let $pc := $c/addr/pcode-zip 
where $c/addr/@country = "Canada" 
order by $c/@Cid  
return <contact>{$c/@Cid}{$pc}</contact> 

  这些查询示例相当简单,并且不支持命名空间。要支持命名空间,可以将命名空间添加到查询列出的元素中; 或者可以使用命令 declare default element namespace '${namespace_uri}'; 声明默认命名空间。

  清单 11 显示了使用命名空间声明的一个 XML 文档。

清单 11. 具有命名空间的 XML 文档

<customerinfo xmlns="http://poindustry.org" Cid="1001"> 
  <name>Kathy Smith</name> 
  <addr country="Canada"> 
    <street>25 EastCreek</street> 
    <city>Markham</city> 
    <prov-state>Ontario</prov-state> 
    <pcode-zip>N9C 3T6</pcode-zip> 
  </addr> 
  <phone type="work">905-555-7258</phone> 
</customerinfo> 

  由于正在处理的是一个具有单一命名空间声明的简单示例, 因此可使用两种方法中的任意一种查询此文档。

  清单 12 声明了默认命名空间。您无需将查询中的元素引用更改为包含命名空间, 因为默认情况下,它们会访问此单一命名空间。

清单 12. 默认命名空间

xquery 
declare default element namespace = "http://poindustry.org"; 
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo 
return $c/addr/city 

  通过定义用作命名空间快速引用的命名空间前缀(比如 cust-ns), 清单 13 利用了多个命名空间。定义了命名空间之后,结合使用此命名空间前缀和引用的任意元素名称。

清单 13. 命名空间前缀

xquery 
declare namespace cust-ns = "http://poindustry.org"; 
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/cust-ns:customerinfo 
return $c/cust-ns:addr/cust-ns:city 

  对于清单 12 和清单 13 中的命名空间示例,记住,分号是一种典型的查询语句结束符。 使用命名空间时,将语句结束符更改为一个不同的字符,比如井号(#)。

  转换和更新

  本节介绍更新 XML 文档中具体内容(元素或属性)的查询。介绍的查询使用了 XQuery Update Facility,这是 XQuery 1.0 的语言和语义的更新。可使用此类型的查询更新、替换、删除 XML 文档的内容,也可以将内容插入 XML 文档中。 这种更改适用于数据库的数据或查询返回的数据。不同操作的查询语法稍有不同。清单 14 显示了替换查询的一个基本语法示例。

清单 14. 基本语法(替换)

UPDATE ${table} 
SET ${xml_col} = XMLQUERY(' 
transform 
copy $$x := ${xquery_expression} 
modify do replace value of ${xquery_expression} 
with ${xquery_expression} 
return ${xquery_expression}') 
WHERE ${expression} 

  下面是修改语法以显示对其他转换操作支持的示例。

  清单 15 更新了具体客户的 city 元素值。注意, transform 是查询的可选部分。所以可在后续一些示例中忽略它。

清单 15. 替换示例

UPDATE customer 
SET info = XMLQUERY(' 
transform 
copy $c := $INFO 
modify do replace value of $c/customerinfo/addr/city 
with "Toronto" 
return $c') 
WHERE CID =1001 

  清单 16 删除了具体客户的 city 元素。

清单 16. 删除示例

UPDATE customer 
SET info = XMLQUERY(' 
copy $c := $INFO 
modify do delete $c/customerinfo/addr/city 
return $c') 
WHERE CID =1001 

  插入很有趣,因为您需要说明在文档的何处插入信息。 清单 17 没有说明在文档的何处插入新元素。实际插入位置是不确定的。

清单 17. 插入示例

UPDATE customer 
SET info = XMLQUERY(' 
copy $c := $INFO 
modify do insert <city>Toronto</city> 
into $c/customerinfo/addr 
return $c') 
WHERE CID =1001 

  如果您需要具体位置,可查看插入数据的许多可选方法之一。 清单 18 在 phone 元素后插入了数据。

清单 18. 在元素后插入数据的示例

UPDATE customer 
SET info = XMLQUERY(' 
copy $c := $INFO 
modify do insert <phone type="cell">905-555-7272</phone> 
after $c/customerinfo/phone 
return $c') 
WHERE CID =1001 

  清单 19 在 addr 内插入了一个作为首个子元素的元素。

清单 19. Insert first 示例

UPDATE customer 
SET info = XMLQUERY(' 
copy $c := $INFO 
modify do insert <company-name>ACME Co</company-name> 
as first into $c/customerinfo/addr 
return $c') 
WHERE CID =1001 

  清单 20 在 addr 内插入了一个作为最后一个 子元素的元素。

清单 20. Insert last 示例

UPDATE customer 
SET info = XMLQUERY(' 
copy $c := $INFO 
modify do insert <company-name>ACME Co</company-name> 
as last into $c/customerinfo/addr 
return $c') 
WHERE CID =1001 

  清单 21 在文档的 addr 元素前添加了一个元素。

清单 21. Insert before 示例

UPDATE customer 
SET info = XMLQUERY(' 
copy $c := $INFO 
modify do insert <email>ksmith@acme.com</email> 
before $c/customerinfo/addr 
return $c') 
WHERE CID =1001 

  清单 22 通过将 addr 元素更改为 address 重命名了现有元素。

清单 22. 重命名示例

UPDATE customer 
SET info = XMLQUERY(' 
copy $c := $INFO 
modify do rename $c/customerinfo/addr 
as "address" 
return $c') 
WHERE CID =1001 

  清单 23 显示了一个转换查询,该查询仅修改了查询结果,并未更改数据库的内容。

清单 23. XQuery 重命名示例

xquery 
copy $c := db2-fn:sqlquery('select INFO from CUSTOMER where CID =1001') 
modify do rename $c/customerinfo/addr 
as "address" 
return $c 

  使用 SQL/XML 创建查询

  本节提供了使用 SQL/XML 创建查询的示例。

  基本 SQL/XML 查询

  一个好的出发点是查看 SQL/XML 查询的精简语法,如清单 24 所示。

清单 24. SQL/XML 查询的语法

SELECT XMLQUERY('${xquery_expression}') 
FROM ${table_name} 
WHERE XMLExists('${xquery_expression}') 

  有几种方法可以使用具有不同类型的 XQuery 表达式的语法。首先查看包含路径表达式的一个示例。

  清单 25 显示了一个查询,此查询获取居住于 city Markham 的客户的 name。XMLExists 谓词用于确定 XQuery 表达式返回一个还是多个项序列。注意,您需要使用方括号 ([ ]) 括住 XQuery 表达式内的任何值谓词。这样做可确保对表达式的评估与语义预期的一样。如果您省略了此方括号,则 XQuery 表达式的结果总会返回一个序列,并使 XMLExists 总是为 true。

清单 25. 使用谓词

SELECT XMLQUERY('$INFO/customerinfo/name') 
FROM CUSTOMER 
WHERE XMLEXISTS('$INFO/customerinfo/addr[city= "Markham"]') 

  接下来,查看另一个示例 FLOWER 表达式和 XMLQUERY 的基本示例。 清单 26 属性为 Cid > 1002 的客户的 addr 元素,其中 country = "Canada"。

清单 26. FLWOR 和 XMLQUERY

SELECT XMLQUERY('for $i in $INFO/customerinfo/addr 
  return $i') 
FROM CUSTOMER 
WHERE XMLEXISTS('let $i := $INFO/customerinfo 
  where $i/@Cid > 1002 
  and $i/addr/@country = "Canada" 
  return $i') 

  XMLTable

  有时当您需要根据 XML 文档的信息返回关系表时,可使用 XMLTable 生成此结果。

  XMLTable 语法如清单 27 所示。

清单 27. XMLTable 语法

SELECT X.${new_col1_name}, X.${new_col2_name}, ${table}.${col} 
FROM XMLTable(${row_generating_xquery_expression} 
COLUMNS  
${new_col1_name} ${new_col1_data_type} PATH '${column_generating_xquery_expression}', 
${new_col2_name} ${new_col2_data_type} PATH '${column_generating_xquery_expression}' 
) AS X 

  清单 28 提供了一个使用 XMLTable 的简单示例。您正在基于 XML 文档的两个值返回行。 XML 文档返回的两个元素都显示在自己的列中。使用 X.* 表明您想返回 XMLTable 提供的所有列。

清单 28. 使用 X*

SELECT X.* 
FROM customer, 
XMLTABLE('$INFO/customerinfo' 
COLUMNS 
 custname VARCHAR(20) PATH 'name', 
 city VARCHAR(20) PATH 'addr/city') AS X 

  除了根据 XML 文档的信息返回列之外,还可以从关系数据返回列,如清单 29 所示。

清单 29. 从关系数据返回列

SELECT customer.CID, X.* 
FROM customer, 
XMLTABLE('$INFO/customerinfo' 
COLUMNS 
 custname VARCHAR(20) PATH 'name', 
 city VARCHAR(20) PATH 'addr/city') AS X 

  清单 30 添加了一个新 XML 类型的列,其中可立刻构建一个新 XML 文档。

清单 30. 添加新列

SELECT customer.CID, X.* 
FROM customer, 
XMLTABLE('$INFO/customerinfo' 
COLUMNS 
 custname VARCHAR(20) PATH 'name', 
 city VARCHAR(20) PATH 'addr/city', 
 newXML XML PATH '<newXML>{addr/pcode-zip}</newXML>') AS X 

  结束语

  本文提供了使用 XML 数据和 DB2 pureXML 时的查询选项快速概述。 目的是为您提供快速熟悉 DB2 pureXML 的简单可访问参考。与学习其他编程语言一样,提高技能的最好方法是编写查询。

    >>更多交流,请到 ChinaUnix【DB2论坛】:http://bbs2.chinaunix.net/forum-22-1.html

网友评论 已有0位网友发表了看法

  • 验证码:
    【输入评论后显示验证码,均为大写字母,点击图片更新】
        
 
 论坛最新热点更多>> 
· DB2高CPU
· 飞天的DB2数据库管理公开课培训...
· DB2创建表空间的问题
· 求助,DB2联合数据库访问的性能
· 请教高人!
· crontab 中调用shell 读取DB2数据
· IBM China招聘数据库解决方案工...
· 求:db2 V9.5在solaris上的安装...
· DB2 iSeries SQLCODE:-104 SQL...
· 求解动态SQL难题
 论坛热门讨论更多>> 
· 关于DB2的内存分配
· 帮帮忙阿,怎么实现大数据量从...
· DB2 DB2备份恢复数据库步骤(自...
· DB2编程序小小技巧
· 【通知】DB2版发帖排行前50名有...
· 求助:DB2中有没有快速清空表的命令
· IBM dW网站DB2整理,6月8日更新...
· 请问谁有DB2的学习资料?
· db2中有关于表空间的信息放在那...
· 招聘DB2工程师
 本周十大热点新闻 
· 详解360系列产品 将重回苹果AP...
· 小伙毕业旅行从澳大利亚骑车回浙江
· 台湾,我来了----台湾八日游第一天
· 明星纷抢红馆开演唱会 谢霆锋年...
· 360深陷下架门:或因隐私问题遭...
· 美10岁女生拼出新分子结构将研...
· 环卫工弄脏挡道轿车遭暴打续:...
· 支付宝一家独大格局开始洗牌:1...
· 永中注册商标价值几何?
· 造型设计已经定型 全新QQ将于明...
 本周十大争议新闻 
· 长安大学两男生为救同学溺水身亡
· 网帖曝光现役军人回家探亲时拍...
· 58同城回应虚假信息问题:建立...
· 资料:话剧《笑面人》演员-刘端端
· 青岛建设银行员工晒工资和支出...
· 《加勒比海盗4》杰克船长是镇台...
· 《甄嬛传》演员阵容强大 孙茜演...
· 资料图片:《我爱记歌词》领唱...
· 资料图片:《麻辣女兵》主要演...
· 新版《西游记》坎坷上路 减少6...
 
 
 

Copyright © 2001-2010 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们
 

京ICP证:060528号