开发者

SQL Server 2008 XML query issue

开发者 https://www.devze.com 2023-01-06 21:52 出处:网络
I am using SQL Server 2008 Enterprise + VSTS 2008 + C# + .Net 3.5 + ASP.Net + IIS 7.0 to develop a simple web application. In my database table, I have a XML type column. The content is like below,

I am using SQL Server 2008 Enterprise + VSTS 2008 + C# + .Net 3.5 + ASP.Net + IIS 7.0 to develop a simple web application. In my database table, I have a XML type column. The content is like below,

I want to get AdditionalInfoList of all rows in the table if Title contains "software engineer" or Info contains "Software Development". My question is how to write such que开发者_如何学JAVAry efficiently?

<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>


You need to do something like this:

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%'

That should give you all the entries you're interested in.

Explanations:

The CROSS APPLY creates a "dummy" table which you need to give a name to - here: Tbl(People). What that name is doesn't really matter, and it's not case sensitive, so Tbl and tbl are identical.

If you want to Guid and the type as separate values from the <AdditionalInfoList>, you need to use this query here:

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%'

You basically have to do a second CROSS APPLY (that'll hurt your performance!) to get the "additional info" list for each of the entries from Tbl.Person and extract the Guid and the type value from that.

Check out the SQL Server 2005 XQuery and XML DML introduction - about in the middle of the article, there's a section on how to use the .nodes() function. Very helpful!

0

精彩评论

暂无评论...
验证码 换一张
取 消