为DB2 pureXML编写XQuery和SQL / XML查询

本文为使用DB2 pureXML查询XML数据提供了快速参考。 本文介绍与一些常见查询相关的语法,包括SQL格式的XQuery和XQuery格式SQL / XML。 即使在这两种格式之间进行选择,通常也可以通过多种方式编写大多数查询以达到相同的结果。

本文主要针对熟悉XML的软件设计师,设计师和开发人员。 本文假定您正在使用IBM开发工具(例如Rational®Software Architect,Rational Application Developer,Optim®Development Studio或InfoSphere™Data Architect)在DB2中使用XML数据。

搭建环境

首先设置您的环境以使用查询。

访问模板

本文中每个查询示例所使用的语法均源自IBM工具随附的编辑器模板中的内容。 要访问工具中的模板集,请完成以下步骤:

  1. 导航至窗口>首选项
  2. 在“首选项”中,导航到“ 数据管理”>“ SQL开发”>“ SQL和XQuery编辑器”>“模板” ,如图1所示。
  3. 查看可用模板,导入其他人提供的模板,或更新模板并导出它们以与他人共享。
图1. SQL和XQuery模板视图
SQL和XQuery模板列表

编辑SQL或XQuery脚本时,可以通过使用编辑器窗口中的CTRL + Space组合键来访问和使用可用模板。

设置数据库表

本文中的示例将SAMPLE数据库表与DB2提供的XML数据一起使用。 您可以将这些示例作为DB2第一步的一部分进行安装,如图2所示,或者在安装后从命令行使用db2sampl -xml来安装。

图2.使用第一步配置样本数据
通过第一步配置示例数据,并选择XML和SQL对象以及数据

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

图3. SAMPLE数据库中的CUSTOMER表视图
客户表图标

清单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计算布尔值。
有条件的
使用ifthenelse来评估测试表达式的值是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列中的一部分文档。 在查询的末尾,包含一个XPath表达式以从XML文档中检索name元素。

清单3.返回文档的子集
xquery db2-fn:sqlquery("select INFO from CUSTOMER where CID = 1000")/customerinfo/name

在这种情况下,您对INFO列中的所有XML文档都感兴趣。 然后,对于每个文档,使用Path表达式返回name元素。

清单4显示了xmlcolumn语法。

清单4. XMLcolumn语法
xquery db2-fn:xmlcolumn('${schema}.${table}.${column}')${xquery_expression}

清单5在INFO列中给出了所有XML文档。 然后,对于每个文档,使用Path表达式返回name元素。

清单5. INFO列中的XML文档
xquery db2-fn:xmlcolumn('CUSTOMER.INFO')/customerinfo/name

FLWOR

在使用XQuery的常用方法是向包括下列条款,其中一些是可选的写查询:F,L,W这里,通过即刻申请,和R E打开。 这些缩写为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是一个简单的FLWOR查询的示例,该查询检索与每个customerinfo元素的每个address关联的city元素。

清单7.简单的FLWOR
xquery
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo 
return $c/addr/city

清单8在上一个查询中添加了一个限制,以限制仅返回属性Cid = 1001customer返回city

清单8.带回城市的FLWOR
xquery
for $c in db2-fn:xmlcolumn("CUSTOMER.INFO")/customerinfo 
where $c/@Cid = 1001 
return $c/addr/city

清单9点提取名字对他们来说,客户prov-state是安大略省,并通过按字母顺序排列的结果name

清单9.安大略省的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来为居住在加拿大的客户分配一个变量来保存pcode-zip值,然后按Cid将结果按字母顺序排列。 然后,代码构造一个新的XML元素<contact> ,其中包含Cidpcode-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

清单13通过定义名称空间前缀(例如cust-ns )来利用多个名称空间,以用作对该名称空间的简写引用。 定义后,请使用此命名空间前缀以及您引用的任何元素名称。

清单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文档。 可以对数据库中的数据进行此更改,也可以将其应用于查询返回的数据。 当您执行不同的操作时,查询语法会略有变化。 清单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}

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

清单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.插入第一个示例
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.插入最后一个示例
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.在示例之前插入
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显示了一个查询,以获取居住在Markham city的客户的nameXMLExists谓词用于确定XQuery表达式是否返回一个或多个项目的序列。 请注意,您需要使用方括号([])包围XQuery表达式内的所有值谓词。 这样做可确保对表达式的求值符合语义上的期望。 如果省略方括号,则XQuery表达式的结果将始终返回序列,而XMLExists将始终为true

清单25.使用谓词
SELECT XMLQUERY('$INFO/customerinfo/name')
FROM CUSTOMER
WHERE XMLEXISTS('$INFO/customerinfo/addr[city= "Markham"]')

接下来,看看另一个使用FLWOR表达式和XMLQUERY的基本示例。 清单26返回具有属性Cid > 1002country = "Canada"的客户的addr元素。

清单26.带XMLQUERY的FLWOR
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')

XML表格

有时您需要根据XML文档中的信息返回关系表。 您可以使用XMLTable创建这样的结果。

清单27展示了XMLTable语法的最基本概念。

清单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时使用。 与学习任何编程语言一样,提高技能的最佳方法是编写查询。 除了使用SAMPLE数据库外,请参阅“其他主题的参考资料”。


翻译自: https://www.ibm.com/developerworks/data/library/techarticle/dm-1006queriespurexml/index.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值