2012-01-12 119 views
3

我一直在争取一段时间,似乎我很接近但并不完全在那里。我有看起来像这样的一个数据库中的列:使用TSQL解析/查询XML

<document> 
<items> 
<item name="one">one is the first number</item> 
<item name="two">two is the second number</item> 
</items> 
</document> 

在这个例子中,我需要查询并返回“二是第二个数字”。我也想在不创建临时表的情况下执行此操作。目前,我有:

create table #test (item1 xml) 
insert into #test (item1) 
values ('<document> <items> <item name="one">one is the first number</item> <item name="two">two is the second number</item> </items> </document>') 

select item1.value('(/document/items/item)[2]', 'nvarchar(max)') from #test 
select item1.query('/document/items/item[@name="two"]') from #test 

的第一选择返回正确的值,但我需要知道它的第二个“索引” 第二返回我想要什么,但它返回整个节点的两个..

我错过了什么?而且,有没有简单的方法来使用XML而不转换为临时表?

回答

6

我也想做到这一点,而无需创建临时表

您可以使用一个变量的数据类型的XML。

declare @xml xml 

set @xml = 
'<document> 
    <items> 
    <item name="one">one is the first number</item> 
    <item name="two">two is the second number</item> 
    </items> 
</document>' 

select @xml.value('(/document/items/item[@name="two"])[1]', 'nvarchar(max)') 

或者您可以在查询中将您的字符串转换为XML。

select cast(
      '<document> 
       <items> 
       <item name="one">one is the first number</item> 
       <item name="two">two is the second number</item> 
       </items> 
      </document>' as xml 
      ).value('(/document/items/item[@name="two"])[1]', 'nvarchar(max)') 

你的第一个查询使用.value()这是正确的,你的第二个查询具有正确的XQuery表达式。当使用.value()时,您需要使用返回单个值的XQuery表达式。这会给你所有的物品节点@name是两个/document/items/item[@name="two"])。最后添加[1]确保您只会在XML中第一次出现@name是两个。

0

(第一关,而不是一个临时表,你可以使用xml类型的变量,因为我做的下面,这样的变量可以直接从字符串文字分配)

所以我认为你的意思是你想要的与nametwo,在这种情况下,你只需要在你在value()通话使用XPath适当的条件下item节点的文本值:

DECLARE @x xml 

SET @x = '<document> <items> <item name="one">one is the first number</item> 
    <item name="two">two is the second number</item> </items> </document>' 

SELECT @x.value('(/document/items/item[@name="two"])[1]', 'nvarchar(max)') 

-------------------------------------------------------------- 
two is the second number 

(1 row(s) affected)