2009-09-08 52 views
7

該SQL只返回第一個Activity元素。我如何選擇全部?如果我在查詢中刪除了[1],那麼會出現「value()需要單身人士」的錯誤。在SQL Server中使用value()從xml列獲取多條記錄

DECLARE @myDoc xml 
    SET @myDoc = 
    '<Root> 
     <Activities> 
      <Activity>This is activity one</Activity> 
      <Activity>This is activity two</Activity> 
      <Activity>This is activity three</Activity> 
     </Activities> 
    </Root>' 

    SELECT @myDoc.value('(/Root/Activities/Activity)[1]', 'varchar(100)') 

回答

15

感謝埃德,但我發現了一個更簡單的版本:

SELECT T.C.value('.', 'varchar(100)') as activity 
FROM @myDoc.nodes('(/Root/Activities/Activity)') as T(C) 

雖然從「過於複雜」的例子似乎令人擔憂的是簡單..

+1

如果XML標記出現多次,我想選擇多少次? http://stackoverflow.com/questions/26426412/how-to-ens-and-sql-is-able-to-read-all-xml-tag-data – SearchForKnowledge

+0

什麼是T和什麼是C –

+0

T是一個別名用於由節點函數創建的派生表。該節點函數返回一段xml,其中包含所有Activity節點名稱和值(如果有的話,還會返回任何子節點和值)。 C是列別名,在這種情況下,它將xml分解成該列每一行上的'Activity'節點。 – Davos

2

這有效,但似乎不必要的複雜。可能有一個更簡單的方法。

DECLARE @myDoc xml 
    SET @myDoc = 
    '<Root> 
     <Activities> 
      <Activity>This is activity one</Activity> 
      <Activity>This is activity two</Activity> 
      <Activity>This is activity three</Activity> 
     </Activities> 
    </Root>' 

SELECT activity.VALUE('(//Activity)[1]','varchar(100)') AS activity 
FROM (
     SELECT NewTable.activity.query('.') AS activity 
     FROM (SELECT 1 AS col1) AS t 
     CROSS APPLY @myDoc.nodes('(/Root/Activities/Activity)') AS NewTable(activity) 
    ) AS x 
0

這裏是另一種情況及解決方法:我正在尋找使用一個查詢來選擇兩個元素的情況。

CREATE TABLE #Table1 (ID INT IDENTITY(1,1),XMLDoc XML) 

INSERT INTO #Table1 VALUES (' 
<bookstore> 
<name>Bookstore1</name> 
<location>Location1</location> 
<book> 
    <title>Titile1</title> 
    <price>40</price> 
    </book> 
</bookstore>') 

INSERT INTO #Table1 VALUES (' 
<bookstore> 
    <name>Bookstore2</name> 
<location>Location2</location> 
<book> 
    <title>Titile2</title> 
    <price>50</price> 
</book> 
</bookstore>') 


SELECT ID, 
T.c.value('title[1]','varchar(50)') AS 'BookTitile', 
T.c.value('price[1]','decimal(18,2)') AS 'Price' 
FROM #Table1 
CROSS APPLY #Table1.XMLDoc.nodes('/bookstore/book') T(c) 

DROP TABLE #Table1 

您可以根據需要對此進行修改以包含XMLNamespaces。 解決方案最初發現於:https://social.msdn.microsoft.com/Forums/sqlserver/en-US/35e75e32-9ffb-4a30-8637-2cc928554763/selecting-multiple-values-from-multiple-rows-of-xml?forum=sqlxml

相關問題