2012-01-12 90 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)