views:

351

answers:

2

This SQL only returns the first Activity element. How do I select them all? If I remove the [1] in the query I get an error that "value() requires a singleton".

 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)' )
A: 

This works, but seems unnecessarily complex. There may be an easier way.

 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
Ed Harper
+1  A: 

Thanks Ed, but I found an easier version:

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

Though from your "unnecessarily complex" example it seems worryingly simple..

Graeme