本文为使用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工具随附的编辑器模板中的内容。 要访问工具中的模板集,请完成以下步骤:
- 导航至窗口>首选项 。
- 在“首选项”中,导航到“ 数据管理”>“ SQL开发”>“ SQL和XQuery编辑器”>“模板” ,如图1所示。
- 查看可用模板,导入其他人提供的模板,或更新模板并导出它们以与他人共享。
图1. SQL和XQuery模板视图
编辑SQL或XQuery脚本时,可以通过使用编辑器窗口中的CTRL + Space组合键来访问和使用可用模板。
设置数据库表
本文中的示例将SAMPLE数据库表与DB2提供的XML数据一起使用。 您可以将这些示例作为DB2第一步的一部分进行安装,如图2所示,或者在安装后从命令行使用db2sampl -xml来安装。
图2.使用第一步配置样本数据
本文中的示例查询使用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
计算布尔值。
有条件的
-
使用
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
列中的一部分文档。 在查询的末尾,包含一个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 = 1001
的customer
返回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>
,其中包含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
清单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
的客户的name
。 XMLExists
谓词用于确定XQuery表达式是否返回一个或多个项目的序列。 请注意,您需要使用方括号([])包围XQuery表达式内的所有值谓词。 这样做可确保对表达式的求值符合语义上的期望。 如果省略方括号,则XQuery表达式的结果将始终返回序列,而XMLExists
将始终为true
。
清单25.使用谓词
SELECT XMLQUERY('$INFO/customerinfo/name')
FROM CUSTOMER
WHERE XMLEXISTS('$INFO/customerinfo/addr[city= "Markham"]')
接下来,看看另一个使用FLWOR表达式和XMLQUERY的基本示例。 清单26返回具有属性Cid > 1002
且country = "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