既然已经尝到了甜头儿,市场营销部门对查询数据的要求就越来越高了。他们想知道在一个特定地区(具有特定的邮政编码)某类产品售出了多少。邮政编码代表特定区域,该区域中可能售出了大量产品,或者有大量客户投诉。这种信息可以帮助市场营销人员和产品经理判断哪些产品在哪些销售区域畅销,并将产品与邮政编码相关联。市场营销部门可以考虑在一个区域中哪些产品应该停止销售,根据某地区的产品畅销度确定市场营销重点。
我们将使用 SQL/XML 函数 XMLQUERY() 实现这个查询。用 SQL/XML 进行查询可以结合这两种技术的长处。例如,可以使用 SQL/XML 执行以下操作:
我们将在 XQuery 中使用 (1)、(2) 和 (5) 项操作。为了简单,我们不对示例进行参数化,并假设我们感兴趣的是 “Jewelry” 产品类别在邮政编码为 “79081” 的地区的销售情况。但是,本文提供的应用程序代码(见本文末尾的 下载 一节)包含的查询允许任何类别或邮政编码的参数。
清单 18. 获取特定邮政编码地区中特定产品类别总销售量的 SQL/XML 查询
| select name, xmlquery( 'declare default element namespace "http://www.ibm.com/developerworks"; let $total := sum ( for $i in $t//category let $sum := count($i/item) where $i/@type = "Jewelry" return $sum ) return <total>{$total}</total>' passing data as "t" ) as data from teamroom.documents where xmlexists( 'declare default element namespace "http://www.ibm.com/developerworks"; $t/marketinfo/sales/customer/address[zip = "79081"]' passing data as "t" ) |
这个 SELECT 语句对于每个地区返回一行,地区名由 name 列表示。另外,对于每一行,返回一个有效的 XML 文档,其中只包含一个根元素
在 SQL 级上执行的另一项处理是,我们不希望 XMLQUERY() 对列中的所有 XML 文档执行操作。我们希望将查询的范围限制在包含邮政编码为 “79081” 的客户的行。找到这些行之后,只对它们执行 XQuery。也就是查询这些行中的所有客户购买记录,无论其邮政编码是否为 “79081”。
这个过滤处理是在 SQL WHERE 子句中用 SQL/XML XMLEXISTS() 函数谓词实现的。XMLEXISTS 谓词判断一个 XQuery 表达式是否返回一个元素序列。在我们的示例中。传递给 XMLEXISTS() 的 XQuery 表达式是一个简单的 XPath 表达式,其中的 $t 是 XML 列 data:$t/marketinfo/sales/customer/address[zip = "79081"]。
这个 XPath 表达式可以解释为:返回邮政编码为 “79081” 的 address 元素的序列。如果指定的 XPath 返回一个空序列,那么 XMLEXISTS 返回 false。否则返回 true。既然 SQL 已经帮助我们获得了 XML 文档的子集,XQuery 的操作范围就确定了;XQuery 使用一个绑定到变量 $total 的 let。$total 被赋值为一个 FLWOR 表达式的结果。对于类别类型为 “Jewelry”(where $i/@type = "Jewelry")的 XML 文档中的任何
这返回每个客户的销售额。将结果传递给 sum() 函数,从而求出某个类别的所有客户的总销售额。现在获得了 $total。因为我们希望返回 XML,所以将总销售额封装在
要想了解在 DB2 9 中使用 XQuery 的更多信息,请参考 DB2 XML Guide(参考资料 一节中提供了这个文档的链接)。