2010-07-14 124 views
0

我正在使用SQL Server 2008 Enterprise + VSTS 2008 + C#+ .Net 3.5 + ASP.Net + IIS 7.0开发一个简单的Web应用程序。在我的数据库表中,我有一个XML类型的列。内容如下,SQL Server 2008 XML查询问题

如果Title包含“software engineer”或Info包含“Software Development”,我想获取表中所有行的AdditionalInfoList。我的问题是如何有效地编写这样的查询?

<People> 
    <Item Name="Username" Value="George" /> 
    <Item Name="Info" Value="Software Development Information" /> 
    <Item Name="Title" Value="Software Engineer in Backend" /> 
    <AdditionalInfoList> 
    <AdditionalInfoListItem Guid="xxx" type="type1" /> 
    <AdditionalInfoListItem Guid="yyy" type="type2" /> 
    </AdditionalInfoList> 
</People> 
+0

我目前的解决方案是将所有XML读取到一个XML字符串中,然后解析XML字符串,我认为效率较低。我想找到更有效的解决方案。 – George2 2010-07-14 08:51:36

回答

2

你需要做这样的事情:

SELECT 
    t.ID, -- or whatever you need from the table where the XML is located 
    tbl.People.query('AdditionalInfoList') 
FROM 
    dbo.YourTable t 
CROSS APPLY 
    t.(xmlcolumn).nodes('/People') AS Tbl(People) 
WHERE 
    tbl.People.value('(Item[@Name="Info"]/@Value)[1]', 'varchar(50)') LIKE '%Software Development%' 
    OR 
    tbl.People.value('(Item[@Name="Title"]/@Value)[1]', 'varchar(50)') LIKE '%Software Engineer%' 

这应该给你所有你感兴趣的条目

说明

CROSS APPLY创建一个“虚拟”表,你需要给一个名字 - 在这里:Tbl(People)。那个名字并不重要,并且不区分大小写,所以Tbltbl是相同的。

如果你想GUID从<AdditionalInfoList>类型为不同的值,你需要在这里使用此查询:

SELECT 
    t.ID, 
    --tbl.People.value('(Item[@Name="Info"]/@Value)[1]', 'varchar(50)') AS 'Info', 
    --tbl.People.value('(Item[@Name="Title"]/@Value)[1]', 'varchar(50)') AS 'Title' 
    Adtl.Info.value('(@Guid)[1]', 'varchar(50)') AS 'GUID', 
    Adtl.Info.value('(@type)[1]', 'varchar(50)') AS 'Type' 
FROM 
    @table t 
CROSS APPLY 
    t.xmlcolumn.nodes('/People') AS Tbl(People) 
CROSS APPLY 
    Tbl.People.nodes('AdditionalInfoList/AdditionalInfoListItem') AS Adtl(Info) 
WHERE 
    Tbl.People.value('(Item[@Name="Info"]/@Value)[1]', 'varchar(50)') LIKE '%Software Development%' 
    OR 
    Tbl.People.value('(Item[@Name="Title"]/@Value)[1]', 'varchar(50)') LIKE '%Software Engineer%' 

你基本上已经做了第二次CROSS APPLY(那会伤害你的表现!)从Tbl.Person获得每个条目的“附加信息”列表,并从中提取Guid和类型值。

查看SQL Server 2005 XQuery and XML DML的介绍 - 关于在文章中间,有关于如何使用.nodes()函数的章节。很有帮助!

+0

TBL是什么?以及如何获取每个匹配行的检索信息的GUID和类型? – George2 2010-07-14 09:16:41

+0

对于TBL,我很困惑,因为您正在使用TBL和“tbl”。 – George2 2010-07-14 09:17:34

+0

谢谢,你是否认为你的方法比我以前的解决方案快得多,为什么? – George2 2010-07-14 09:58:07