Sql server 如何编写一个XQuery来访问存储在单独SQL Server表中的XML?

Sql server 如何编写一个XQuery来访问存储在单独SQL Server表中的XML?,sql-server,xquery,xquery-sql,Sql Server,Xquery,Xquery Sql,我创建了一个包含两个表的新数据库来测试SQLServer2008XML功能 如果我要成功地获得所需的行为,我必须创建大约50个表,然后为新项目导入大量XML文件 我的测试环境是这样创建的: create table Employees( idEmployeeFeed bigint primary key IDENTITY(1,1), EmployeeFeed xml ) go create table GeoCountries( CountriesFeed xml )

我创建了一个包含两个表的新数据库来测试SQLServer2008XML功能

如果我要成功地获得所需的行为,我必须创建大约50个表,然后为新项目导入大量XML文件

我的测试环境是这样创建的:

create table Employees(
    idEmployeeFeed bigint primary key IDENTITY(1,1),
    EmployeeFeed xml
)
go

create table GeoCountries(
    CountriesFeed xml
)
go
然后,我在Employees表中加载了大约1000个xml文件,在GeoCountries表中加载了1个文件。 GeoCountries文件包含249个国家的横向/纵向质心坐标,以及国家名称和ISO 3字符国家代码

每个员工都有一个国家代码。我已经在另一个产品中准备好了XQuery,现在需要根据客户机的要求迁移到SQL Server

使用XQuery获得的两个表中的示例数据:

select EmployeeFeed.query('//employee') as employee
from Employees
/* output:
    <employee empID="1111" >
      <displayName>John</displayName>
      <country code="USA" />
    </employee>
    <employee empID="2222" >
      <displayName>Mario</displayName>
      <country code="ITA" />
    </employee>
    ...
*/

select EmployeeFeed.query('//employee/country') as employee
from Employees
/* output:
    <country code="USA" />
    <country code="ITA" />
    ...
*/

select CountriesFeed.query('//country')
from GeoCountries
/* output:
    <country>
      <ISO3166A3>USA</ISO3166A3>
      <ISOen_name>United States</ISOen_name>
      <latitude>38.000</latitude>
      <longitude>-97.000</longitude>
    </country>
    <country>
      <ISO3166A3>ITA</ISO3166A3>
      <ISOen_name>Italy</ISOen_name>
      <latitude>42.833</latitude>
      <longitude>12.833</longitude>
    </country>
    ...
*/

select CountriesFeed.query('//country/ISO3166A3')
from GeoCountries
/* output:
    <ISO3166A3>USA</ISO3166A3>
    <ISO3166A3>ITA</ISO3166A3>
    ...
*/
这是我正在尝试运行的查询:

select EmployeeFeed.query(N'
  let $ccc := //country
  let $ttt := //employee
  for $t in $ttt  
  return
        <geoEmp
        empCode="{ $t/@empID }" 
        countryCode="{ $t/country/@code }" 
        latit="{ $ccc[ISO3166A3 = $t/country/@code]/latitude/text() }" 
        longit="{ $ccc[ISO3166A3 = $t/country/@code]/longitude/text() }"
        />
') as GeoEmployees
from Employees
/* output:
    <geoEmp empCode="1111" countryCode="USA" latit="" longit="" />
    <geoEmp empCode="2222" countryCode="ITA" latit="" longit="" />
    ...
*/
如您所见,国家代码+lat/long预先加载在变量$ccc中,以将其用作查找表,但由于该数据位于另一个SQL表GeoCountries中,因此无法在与SQL表Employees关联的当前XQuery上下文中找到

有没有办法运行一个XQuery来访问存储在不同SQL表中的XML? 如果我迁移,我将有100-200个类似的情况需要处理,并且我需要为这个问题找到一个有效的解决方案。

这个怎么样:

select e.empID as '@empCode', c.code as '@countryCode', c.lat as '@latit', c.long as '@longit' from (
    select e.emp.value('(@empID)[1]', 'int') as empID, e.emp.value('(country/@code)[1]', 'varchar(32)') as code
    from Employees
    cross apply EmployeeFeed.nodes('//employee') e(emp)
) e
inner join (
    select c.country.value('(ISO3166A3)[1]', 'varchar(32)') as code, c.country.value('(latitude)[1]', 'varchar(32)') as lat, c.country.value('(longitude)[1]', 'varchar(32)') as long
    from GeoCountries
    cross apply CountriesFeed.nodes('//country') c(country)
) c on e.code = c.code
for xml path('geoEmp'), type

您能给我们展示一下实际的个人雇员feed和ContriesFeed XML是什么样子的吗?现在,您只向我们展示了从多个XML实例的查询中重建的XML,因此不清楚各个行是什么样子的。谢谢muhmud。您的方法有效,我可以获得所需的输出。我只是担心在代码复杂性和数量方面的开销,这似乎需要从纯xquery转换过来。。。基本上,这里我们将使用一组中间的sql数据,然后使用for xml切换回xml。有没有一种方法可以使用类似fn:doctablename的方法在另一个表中引用xml?我还想知道这种方法是否会导致某种程度的性能下降……如果需要,您可以创建XML索引。但是,如果您想使用Xquery,我认为您必须通过连接或使用sqlvariable-在相同的位置获取xml。即使这样,您仍然需要浏览大部分XML,但这次是在Xquery中。您可以尝试使用where子句来减少这种情况,但是您也可以将其应用于上述情况。我有完全相同的问题,我想知道您是否找到了从XQuery中的另一个表中表示引用xml数据的方法,例如fn:doctablename或fn:CollectionCollectionName?还是这根本不可能?SQL Server 2014的新功能是什么?提前谢谢。