多表查询xml数据库查询_查询包含名称空间的XML数据

多表查询xml数据库查询

对某些人来说,这是一个解决方案。 对其他人来说,它们是绊脚石。 但是,无论您喜欢它们还是讨厌它们,XML名称空间无处不在。 确实,许多开发人员认为它们是必需的。

打开Web服务定义语言(WSDL)文件或SOAP消息,将文字处理文档转换为XML,或浏览特定于行业的XML模式; 您可能会找到对多个名称空间的引用。 如果要查询XML数据,则需要考虑这一点,因为名称空间会更改所有内容。 (嗯,不是全部 。但是名称空间对查询的语义有很大影响。)

忽略名称空间的存在,并且您编写的查询不太可能产生期望的结果。 那是坏消息。 好消息是,学习如何正确查询包含名称空间的XML数据不会花费大量时间。 本文可以帮助您入门。

XML名称空间简介

XML名称空间是W3C XML标准。 实际上,XPath,XML Schema,XQuery和其他XML技术都支持名称空间。 尽管本文没有提供有关名称空间的详细教程,但确实强调了一些关键概念。 要了解有关XML名称空间的更多信息,请参见参考资料部分。

XML名称空间允许XML文档合并来自不同词汇表的元素和属性,而不会产生歧义和处理冲突。 XML名称空间有可能为组织的XML数据提供通用的唯一标记词汇表(元素和属性名称),以及与其他人共享该词汇表的能力。 一些公司依靠命名空间来帮助他们将来自不同来源的XML数据组合在一起,以随着业务需求的发展而对XML模式进行版本化,并促进文档的重用。

尽管如此,许多IT专业人员在应如何使用名称空间上仍存在分歧。 一些人主张在文档和模式中频繁和广泛使用。 其他人敦促谨慎或避免。 如果您对辩论感到好奇,请参阅“ 相关主题”部分。 我不会在这篇文章中陷入困境。 我将仅说明如何查询包含名称空间的XML数据,因为您可能会在工作中遇到名称空间。

那么,名称空间是什么? 它们是由统一资源标识符(URI)标识的唯一XML元素和属性名称的集合。 这些URI通常看起来像网站URL(即,它们包括域名,例如http://www.w3.org ),尽管有时会使用通用资源名称(URN)。 无论哪种情况,URI都不会实际从指定位置检索数据。 如果URI采用URL的形式,则它甚至不需要引用真实的Web页面。 它可以是仅用作标识符的“假” URL。

XML名称空间是使用xmlns关键字声明的。 清单1显示了XML文档中元素的两个有效的名称空间声明。 <employee>元素具有基于URL的URI,而<partner>元素具有基于URL的URI。

清单1.示例名称空间声明
. . . 
<employee xmlns="http://www.bogus.com/employee/1.0"/>
<p:partner xmlns:p="urn:xmlns:bogus:partner1.0"/>
. . .

除了指定的URI类型以外,您是否注意到这些名称空间声明之间的另一个区别? 实际上, <partner>元素包括一个既定义又包含前缀(在此示例中为p )的名称空间。 名称空间前缀的使用是可选的,但不仅限于样式选择。 如果元素具有名称空间前缀,则它属于为该前缀定义的名称空间; 但是,除非它们的子元素也加上前缀,否则它不属于同一名称空间。 包含名称空间声明但不包含名称空间前缀的元素(例如上例中的<employee>元素)属于已声明的名称空间。 除非明确重写,否则它们的子元素也属于同一名称空间。 最后,缺少显式名称空间声明的未前缀元素将绑定到作用域内的默认名称空间。 如果没有这样的绑定,则该元素不属于任何名称空间。

考虑清单2中的示例:

清单2.具有多个名称空间的示例XML文档
<mydoc>
    <employee xmlns="http://www.bogus.com/employee/1.0">
          <name>John Jones</name>
           . . . 
    <employee>
    <p:partner xmlns:p="urn:xmlns:bogus:partner1.0"/>
           <name>Acme Computer Corp.</name>
            . . . 
     </p:partner>
     <department>
	<name>Sales</name>
	. . . 
      </department>
</mydoc>

在这种情况下,员工名称属于<employee>元素( http://www.bogus.com/employee/1.0 )中声明的默认名称空间。 但是,合作伙伴名称不在任何名称空间的范围内。 尽管它是<partner>的子元素,但此<name>元素不会继承其父级的名称空间,因为该名称空间是用前缀声明的。 您可以按以下方式重写该行,以将伙伴的名称信息包括在与其父代相同的名称空间中:

清单3.修改为包含名称空间前缀的元素
<p:name>Acme Computer Corp.</p:name>

最后,部门名称不属于任何名称空间。 这是因为<department>元素中未声明任何名称空间,并且未将其绑定到默认名称空间。

如您所见,通过在单个文档中混合和匹配各种形式的名称空间声明,很容易造成混乱。 通常,如果您可以定义将要使用的XML数据,那么请在使用命名空间时保持一致。 它简化了您的应用程序和查询。 后续各节探讨名称空间的范围如何影响查询。

样品环境

在考虑如何查询包含名称空间的XML数据之前,需要一些示例数据。 为此,我使用DB2 V9来存储和查询有关业务伙伴的XML数据,这些数据将在单个PARTNERS表中维护。 如果计划继续进行,则需要在DB2 UTF-8数据库中创建该表。 (有关数据库创建的说明,请参阅“ DB2 Viper快速入门 ”。)

清单4中的脚本创建该表,并在该表中插入几行(每行包含一个XML文档):

清单4.使用数据创建示例表的脚本
create table partners (id int primary key not null, status varchar(10), details xml);

insert into partners values (111, 'Gold', 
'<company type="public"> 
  <name>Acme Tech</name>
  <specialty>Technology</specialty> 
  <contact>     
    <name>John Smith</name> 
    <title> VP, Business Development </title>     
    <email>js@us.acme_tech.com</email> 
  </contact> 
</company>');

insert into partners values (200, 'Silver', 
'<company xmlns="urn:xmlns:saracco-sample:company1.0" type="public"> 
  <name>Saturnia Ltd</name> 
  <specialty>Technology</specialty>
  <contact> 
    <name>Klaus Fischer</name> 
    <title>Alliance Manager</title>
    <email>klausfischer@uk.saturnia.com</email> 
  </contact> 
</company>');

insert into partners values (222, 'Gold', 
'<co:company xmlns:co="urn:xmlns:saracco-sample:company1.0" type="private"> 
  <name>Maribel Enterprises</name> 
  <specialty>Public relations</specialty>
  <contact> 
     <name>Maribel Payton</name> 
     <title>CEO</title>
     <email>mpayton@maribelent.com</email> 
  </contact> 
</co:company>');

insert into partners values (333, 'Silver', 
'<co:company xmlns:co="urn:xmlns:saracco-sample:company1.0" type="public"> 
  <co:name>Credo International Corp.</co:name> 
  <co:specialty>Manufacturing</co:specialty> 
  <person:contact xmlns:person=
		"http://www.ibm.com/bogus/saracco-sample/person1.0">         
     <person:name>Helen Rakai</person:name> 
     <person:title>Director of Marketing</person:title> 
     <person:email>helen_rakai@credointcorp.com</person:email> 
  </person:contact> 
</co:company>');

insert into partners values (444, 'Silver', 
'<co:company xmlns:co="urn:xmlns:saracco-sample:company1.0" type="private"> 
  <co:name>Raymond Associates</co:name>   
  <co:specialty>Consulting</co:specialty> 
  <person:contact xmlns:person=
		"http://www.ibm.com/bogus/saracco-sample/person2.0">         
     <person:name>Raymond Sanchez</person:name> 
     <person:title>Dr.</person:title>
     <job:title xmlns:job=
		"http://www.ibm.com/bogus/saracco-sample/job1.0">President</job:title> 
     <person:email>drsanchez@ca.rrs.com</person:email>
    <person:comments>Prefers short-term projects</person:comments>  
  </person:contact>
</co:company>');

这些XML文档跟踪有关业务伙伴的类似信息,包括公司名称,专业领域和业务伙伴代表。 但是,每个文档使用命名空间的方式有所不同,并且有些包含多个命名空间。 我有目的地提供了各种名称空间用法的示例,以说明这些名称空间将对后续查询产生的影响。

后面的查询都是设计为从DB2命令行处理器发出的。 在DB2命令窗口中,发出以下命令来设置命令行环境,在该命令行环境中查询语句以百分号( <%> )终止,并且XML输出以易于阅读的方式显示:

清单5.设置DB2命令行环境
db2 -td% -i -d

<%>不是默认的终止符。 在命令行环境中,必须覆盖默认终止字符(分号或“;”),因为它是XQuery中保留的,用于从查询正文中分离出一个序言,例如名称空间声明。

如果愿意,可以使用DB2控制中心的命令编辑器来发出查询。

在SQL / XML和XQuery中使用XPath表达式

查询包含名称空间的XML数据要求您在路径表达式中指定适当的名称空间信息。 SQL / XML和XQuery都支持XPath表达式,这些表达式允许在XML层次结构中进行导航。 如果您还不熟悉如何将路径表达式合并到SQL / XML和XQuery中,请阅读“ 使用SQL / XML 查询DB2 XML数据 ”和“ 使用XQuery查询DB2 XML数据 ”。

现在,让我们逐步完成几个示例任务,并探索如何编写XQueries以检索所需的信息。 我还将向您展示如何编写满足您需求SQL / XML查询。

情况1:返回所有XML“公司”数据

您的第一个任务很简单:检索有关所有业务伙伴的“公司”数据。 如果要获取一组所有合作伙伴XML数据,则可以编写一个简单SQL查询:

清单6.一个SQL查询以检索所有公司数据
select details from partners %

但是,假设您要获取一系列公司数据。 为此,您需要编写一个XQuery。 如果您从未使用过命名空间,则可能会想编写一个查询,例如:

清单7.错误的XQuery来检索所有公司数据
xquery db2-fn:xmlcolumn('PARTNERS.DETAILS')/company %

但是,此查询仅返回示例表中的一个XML文档:

清单8.先前XQuery的输出
<company type="public">
        <name>
                Acme Tech
        </name>
        <specialty>
                Technology
        </specialty>
        <contact>
                <name>
                        John Smith
                </name>
                <title>
                         VP, Business Development
                </title>
                <email>
                        js@us.acme_tech.com
                </email>
        </contact>
</company>

这是因为查询中的路径表达式仅针对没有名称空间的<company>元素。 要检索所有<company>元素,您需要重写查询。 为此,请在路径表达式中使用通配符(*)。 以下XQuery导致DB2检索文档的根节点处的所有<company>元素,而不管名称空间如何:

清单9.修改后的XQuery以检索所有公司数据
xquery db2-fn:xmlcolumn('PARTNERS.DETAILS')/*:company %

在SQL / XML中,此查询可以表示为:

清单10.用于检索所有公司数据SQL / XML查询
select xmlquery('$c/*:company' passing details as "c") 
from partners  
where xmlexists('$c/*:company' passing details as "c")%

您可能想知道为什么WHERE子句出现在此查询中。 严格来说,给出示例数据就没有必要了。 这是因为PARTNERS表中的每个XML文档都包含一个根<company>元素,并且您想要检索所有公司信息,而不管名称空间如何。 但是,如果您的文档中的根<firm>元素存储在PARTNERS.DETAILS中,并且您省略了显示的WHERE子句,那么DB2将为该文档返回一个空记录。 这是由于SQL的语义所致:没有WHERE子句,SQL查询不会从返回的结果集中的表中过滤掉任何行。 因此,如果使用SQL / XML查询XML数据,则必须在WHERE子句中包含XMLExists()函数(或其他过滤谓词),以确保结果中的每一行都不包含一行。

情况2:返回选定名称空间的所有XML“公司”数据

通常,您可能需要将XML数据查询限制为特定的名称空间。 本部分考虑如何获取与urn:xmlns:saracco-sample:company1.0命名空间关联的公司记录的完整XML文档。

使用DB2,必须在查询中声明您感兴趣的名称空间。 清单11声明了后续XQuery表达式的默认名称空间:

清单11.在XQuery中声明一个默认名称空间
xquery declare default element namespace "urn:xmlns:saracco-sample:company1.0";

此子句不能独立运行。 尝试这样做会产生SQL16002N错误。 您要发出的XQuery必须紧跟在名称空间声明之后。 该示例声明一个默认的名称空间,并指示DB2检索与该名称空间相关的所有公司的信息:

清单12.使用默认名称空间的XQuery
xquery declare default element namespace "urn:xmlns:saracco-sample:company1.0";
db2-fn:xmlcolumn('PARTNERS.DETAILS')/company%

给定清单4的内容,DB2返回四个XML记录的序列:

清单13.先前XQuery的输出
<company xmlns="urn:xmlns:saracco-sample:company1.0" type="public">
<name>
	Saturnia Ltd
</name>
<specialty>
	Technology
</specialty>
<contact>
	<name>
		Klaus Fischer
	</name>
	<title>
		Alliance Manager
	</title>
	<email>
		klausfischer@uk.saturnia.com
	</email>
</contact>
</company>
<co:company xmlns:co="urn:xmlns:saracco-sample:company1.0" type="private">
<name>
	Maribel Enterprises
</name>
<specialty>
	Public relations
</specialty>
<contact>
	<name>
		Maribel Payton
	</name>
	<title>
		CEO
	</title>
	<email>
		mpayton@maribelent.com
	</email>
</contact>
</co:company>
<co:company xmlns:co="urn:xmlns:saracco-sample:company1.0" type="public">
<co:name>
	Credo International Corp.
</co:name>
<co:specialty>
	Manufacturing
</co:specialty>
<person:contact xmlns:person="http://www.ibm.com/bogus/saracco-sample/person1.0">
	<person:name>
		Helen Rakai
	</person:name>
	<person:title>
		Director of Marketing
	</person:title>
	<person:email>
		helen_rakai@credointcorp.com
	</person:email>
</person:contact>
</co:company>
<co:company xmlns:co="urn:xmlns:saracco-sample:company1.0" type="private">
<co:name>
	Raymond Associates
</co:name>
<co:specialty>
	Consulting
</co:specialty>
<person:contact xmlns:person="http://www.ibm.com/bogus/saracco-sample/person2.0">
	<person:name>
		Raymond Sanchez
	</person:name>
	<person:title>
		Dr.
	</person:title>
	<job:title xmlns:job="http://www.ibm.com/bogus/saracco-sample/job1.0">
		President
	</job:title>
	<person:email>
		drsanchez@ca.rrs.com
	</person:email>
	<person:comments>
		Prefers short-term projects
	</person:comments>
</person:contact>
</co:company>

结果中不包含Acme Tech的信息,因为其<company>元素不属于声明的名称空间。

清单14显示了一种用SQL / XML表达以前的XQuery的方法:

清单14.具有默认名称空间SQL / XML查询
select xmlquery('declare default element namespace 
   "urn:xmlns:saracco-sample:company1.0"; 
    $c/company' passing details as "c") 
from partners
where xmlexists('declare default element namespace 
   "urn:xmlns:saracco-sample:company1.0"; 
    $c/company' passing details as "c") %

XMLExists()函数将结果限制为与感兴趣的名称空间关联的四个公司记录。

情况3:探索名称空间中的大小写敏感性

考虑一个与清单12所示示例非常相似的查询

清单15.修改了XQuery并进行了名称空间修改
xquery declare default element namespace "urn:xmlns:saracco-sample:Company1.0"; 
db2-fn:xmlcolumn('PARTNERS.DETAILS')/company

在仔细检查此查询时,只有一个字符与前面显示的XQuery不同。 在这种情况下,“ Company1.0”以大写字母开头,而先前的查询将“ company1.0”作为名称空间定义的一部分。 该查询成功执行,但不返回任何记录。 这是因为名称空间和XPath表达式都区分大小写。

如果查询执行没有错误但没有返回任何数据,请仔细检查查询中的路径表达式和名称空间声明。 XQuery和SQL / XML都是如此。

情况4:声明带前缀的名称空间

到目前为止,示例为每个查询声明了默认名称空间。 但是,您也可以声明带有前缀的名称空间,并根据需要在查询中引用该前缀。 如果您通常创建包含名称空间前缀的XML文档,那么这种方法对您来说将是很自然的。 此外,如果查询需要引用属于不同名称空间的XML元素,则必须使用前缀,如本文稍后所述。

这是重写清单12中的XQuery以使用名称空间前缀而不是默认名称空间的方法:

清单16.在XQuery中使用名称空间前缀
xquery declare namespace x="urn:xmlns:saracco-sample:company1.0"; 
db2-fn:xmlcolumn('PARTNERS.DETAILS')/x:company

同样,以下是重写SQL / XML等效项以使用名称空间前缀的方法:

清单17.与先前的XQuery等效SQL / XML
select xmlquery('declare namespace x="urn:xmlns:saracco-sample:company1.0"; 
  $c/x:company' passing details as "c") 
from partners
where xmlexists('declare namespace x="urn:xmlns:saracco-sample:company1.0";  
  $c/x:company' passing details as "c")  %

查询中使用的名称空间前缀可以与数据中使用的前缀不同。 重要的是,前缀已绑定到数据中使用的相同名称空间URI。 您可以在查询中使用带前缀的名称空间,以检索文档中具有默认名称空间的元素,并执行相反的操作。

情况5:检索XML片段

尽管情况1至4检索了存储在DB2中的整个XML文档,但是编写只检索文档片段的查询是很常见的。 当然,名称空间的存在也会影响此类查询。

考虑以下XQuery,它指示DB2检索所有伙伴的公司名称,其中<company>元素及其子<name>元素属于一个公共名称空间( urn:xmlns:saracco-sample:company1.0 ):

清单18. XQuery检索属于特定名称空间的公司名称
xquery declare namespace c="urn:xmlns:saracco-sample:company1.0"; 
db2-fn:xmlcolumn('PARTNERS.DETAILS')/c:company/c:name %

针对示例数据运行时,此查询返回三个XML元素的序列:

清单19.先前XQuery的输出
<name xmlns="urn:xmlns:saracco-sample:company1.0">
Saturnia Ltd
</name>
<co:name xmlns:co="urn:xmlns:saracco-sample:company1.0">
Credo International Corp.
</co:name>
<co:name xmlns:co="urn:xmlns:saracco-sample:company1.0">
Raymond Associates
</co:name>

Maribel Enterprises的记录未返回。 尽管其<company>元素属于查询中指定的名称空间,但其<name>元素却不属于该名称空间。 这是因为记录的<company>元素在表中定义了名称空间前缀。 因为其子节点(包括<name>元素)不包含名称空间前缀,所以它们不属于任何名称空间。

这是在SQL / XML中表达上一个查询的方法:

清单20.与先前的XQuery等效SQL / XML
select xmlquery('declare namespace x="urn:xmlns:saracco-sample:company1.0";
    $c/x:company/x:name' passing details as "c") 
from partners
where xmlexists('declare namespace x="urn:xmlns:saracco-sample:company1.0";
    $c/x:company/x:name' passing details as "c") %

情况6:在单个查询中引用多个名称空间

由于许多XML文档包含与不同名称空间关联的元素,因此您的某些查询可能需要引用多个名称空间。 在这种情况下,只需在查询中声明多个名称空间并根据需要引用每个名称空间。

考虑以下查询,该查询检索各个公司的联系信息:

清单21.在XQuery中使用多个名称空间
xquery declare namespace p="http://www.ibm.com/bogus/saracco-sample/person2.0";
declare namespace c="urn:xmlns:saracco-sample:company1.0"; 
db2-fn:xmlcolumn('PARTNERS.DETAILS')/c:company/p:contact %

给定清单4中的样本数据,DB2返回一条记录,其中包含Raymond Sanchez的联系信息:

清单22.先前XQuery的输出
<person:contact xmlns:co="urn:xmlns:saracco-sample:company1.0" xmlns:person=
	"http://www.ibm.com/bogus/saracco-sample/person2.0">
<person:name>
	Raymond Sanchez
</person:name>
<person:title>
	Dr.
</person:title>
<job:title xmlns:job="http://www.ibm.com/bogus/saracco-sample/job1.0">
	President
</job:title>
<person:email>
	drsanchez@ca.rrs.com
</person:email>
<person:comments>
	Prefers short-term projects
</person:comments>
</person:contact>

这些是其他记录不符合条件的一些原因:

  • 约翰·史密斯(John Smith)的记录没有与他的公司或联系方式数据相关的名称空间。
  • Klaus Fischer的记录共享特定的公司名称空间声明,但是他的联系数据属于查询中未指定的名称空间。 (他的联系数据与urn:xmlns:saracco-sample:company1.0命名空间相关联。)
  • Maribel Payton的记录共享特定的公司名称空间声明,但是她的联系数据不属于任何名称空间。
  • 海伦·拉凯(Helen Rakai)的记录共享特定的公司名称空间声明,但她的联系数据属于另一个名称空间。 ( http://www.ibm.com/bogus/saracco-sample/person1.0代替http://www.ibm.com/bogus/saracco-sample/person2.0 )。

清单23显示了一种用SQL / XML表达此查询的方法:

清单23.与先前的XQuery等效SQL / XML
select xmlquery('declare namespace x="urn:xmlns:saracco-sample:company1.0"; 
   declare namespace y="http://www.ibm.com/bogus/saracco-sample/person2.0";
   $c/x:company/y:contact' passing details as "c") 
from partners
where xmlexists('declare namespace x="urn:xmlns:saracco-sample:company1.0"; 
   declare namespace y="http://www.ibm.com/bogus/saracco-sample/person2.0";
   $c/x:company/y:contact' passing details as "c")

情况7:有关多个名称空间的更多信息

由于起初使用多个名称空间似乎有些棘手,所以考虑另一个稍微复杂一点的示例。 查看此查询,看看您是否可以理解其意图:

清单24.另一个引用多个名称空间的XQuery
xquery declare namespace p="http://www.ibm.com/bogus/saracco-sample/person1.0"; 
db2-fn:xmlcolumn('PARTNERS.DETAILS')/*:company/p:contact/title %

该查询指示DB2检索各个公司的联系人的<title>元素。 它还指定了合格的<company>元素可以与任何命名空间关联, <contact>元素必须属于http://www.ibm.com/bogus/saracco-sample/person1.0命名空间,并且该<title>元素不能属于任何名称空间。

给定样本数据,此查询不返回任何记录。 一条记录(对于Helen Rakai而言)很接近,因为它包含一个根<company>元素,该元素带有一个<contact>子元素,该子元素属于指定的命名空间。 但是,它的<title>元素属于特定的名称空间。 因此,记录与查询的过滤条件不匹配。

情况8:在查询中使用名称空间和属性

案例1到案例7涉及对XML元素节点的查询。 您还需要考虑名称空间如何应用于属性。 情况并非您所期望的。

属性从不从其元素继承名称空间,也从不采用默认名称空间。 如果属性具有前缀,则它属于该前缀指示的名称空间。 如果属性没有前缀,则它没有名称空间。 有关详细信息,请参见“ W3C命名空间建议 ”。 当然,在编写查询时,您需要考虑这些信息。

考虑以下XQuery示例,该示例检索上市公司的名称:

清单25.一个包含名称空间和属性的XQuery示例
xquery declare namespace c="urn:xmlns:saracco-sample:company1.0";
for $x in db2-fn:xmlcolumn('PARTNERS.DETAILS')/c:company 
where $x/@type="public" 
return $x/c:name %

此查询指定合格的<company><name>元素必须属于特定的名称空间( urn:xmlns:saracco-sample:company1.0 )。 此查询中存在名称空间前缀( c )表示。 请注意, @type属性指示公司是公开的还是私有的,不包含名称空间前缀。 因此,此查询产生两条记录:

清单26.先前XQuery的输出
<name xmlns="urn:xmlns:saracco-sample:company1.0">
Saturnia Ltd
</name>
<co:name xmlns:co="urn:xmlns:saracco-sample:company1.0">
Credo International Corp.
</co:name>

如果您为查询中的@type属性指定一个名称空间,如清单27所示,那么所有示例XML文档都不符合条件。 在这种情况下,DB2不返回任何记录:

清单27.修改后的XQuery
xquery declare namespace c="urn:xmlns:saracco-sample:company1.0"; 
for $x in db2-fn:xmlcolumn('PARTNERS.DETAILS')/c:company 
where $x/@c:type="public" 
return $x/c:name %

如果要使用SQL / XML检索上市公司的名称,则可以编写与此查询类似的查询:

清单28.清单25中所示的XQuery的等效SQL / XML
select xmlquery('declare namespace x="urn:xmlns:saracco-sample:company1.0";
 $c/x:company/x:name' passing details as "c") 
from partners
where xmlexists('declare namespace x="urn:xmlns:saracco-sample:company1.0";
 $c/x:company[@type="public"]' passing details as "c") %

案例9:将XML数据转换为关系数据

最后,如何将带有名称空间的XML数据转换为关系数据? 许多现有的应用程序和商业工具(例如查询/报告编写器)被设计为与存储在传统SQL数据类型(例如VARCHAR,INT,DATE等)的列中的数据一起使用。 结果,程序员使用SQL/XML()函数将XML数据动态转换为更传统SQL数据类型。

当然,原始XML数据中存在名称空间会影响您必须如何编写此类“变形”查询。 考虑下一个示例,该示例检索有关状态为“银”的业务伙伴的信息,其公司数据与给定的名称空间相关联。 特别是,查询返回公司的ID和名称,以及公司联系人的姓名和电子邮件地址。

清单29.一个涉及XMLTable()和名称空间SQL / XML查询
select p.id, z.company, z.name, z.email
from partners p, 
xmltable('declare namespace ns="urn:xmlns:saracco-sample:company1.0";
 $c/ns:company' passing details as "c" 
 columns 
    "COMPANY" varchar(30) path 
        'declare namespace ns="urn:xmlns:saracco-sample:company1.0";ns:name',
     "NAME" varchar(30) path '*:contact/*:name',
     "EMAIL" varchar(30) path '*:contact/*:email'
) as z
where p.status = 'Silver' %

该查询的一些方面值得注意。 首先,查询是用SQL / XML编写的。 您不能用纯XQuery(没有SQL)来表示此特定查询,因为要返回的数据包括存储在SQL整数列中的公司ID。 XQuery处理XML数据类型,而不是关系数据类型。 其次,SQL / XML查询中的每个路径表达式都需要单独的名称空间声明。 因此,此查询在此示例中两次声明urn:xmlns:saracco-sample:company1.0的名称空间。 最后,合格公司代表的姓名和电子邮件地址可以属于任何名称空间(或不属于任何名称空间),因此NAME和EMAIL列的路径表达式不需要声明名称空间。

DB2返回此查询的三行结果集:

清单30.先前SQL / XML查询的输出
ID          COMPANY                   NAME                 EMAIL                         
----------- ------------------------- -------------------- ------------------------------
 200        Saturnia Ltd                Klaus Fischer       klausfischer@uk.saturnia.com  
 333        Credo International Corp.   Helen Rakai         helen_rakai@credointcorp.com  
 444        Raymond Associates          Raymond Sanchez     drsanchez@ca.rrs.com

摘要

如果您想了解XQuery和SQL / XML的基础知识以外的知识,则必须了解文档和消息中XML名称空间的存在如何影响其查询的语义。 如果不这样做,可能会产生意想不到的或不期望的结果。 幸运的是,学习如何查询包含名称空间的XML文档并不难。 本文提供了一些示例来帮助您入门。

致谢

感谢Matthias Nicola,Bryan Patterson和Bert van der Linden对本文的审阅。


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

多表查询xml数据库查询

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值