Given a table with an XML column, how can I expand a list stored therein, into a relational rowset?
Here is an example of a similar table.
DECLARE @test TABLE
(
id int,
strings xml
)
insert into @test (id, strings)
select 1, '<ArrayOfString><string>Alpha</string><string>Bravo</string><string>Charlie</string></ArrayOfString>' union
select 2, '<ArrayOfString><string>Bravo</string><string>Delta</string></ArrayOfString>'
I would like to obtain a rowset like this.
id string
-- ------
1 Alpha
1 Bravo
1 Charlie
2 Bravo
2 Delta
I have figured out that I can use the nodes method to output the XML value for each id like this
select id, R.strings.query('/ArrayOfString/string') as string
from @test cross apply strings.nodes('/ArrayOfString/string') as R(strings)
returning
id string
-- ------
1 <string>Alpha</string><string>Bravo</string><string>Charlie</string>
1 <string>Alpha</string><string>Bravo</string><string>Charlie</string>
1 <string>Alpha</string><string>Bravo</string><string>Charlie</string>
2 <string>Bravo</string><string>Delta</string>
2 <string>Bravo</string><string>Delta</string>
and that I can append [1] to the query to get only the first string
select id, R.strings.query('/ArrayOfString/string[1]') as string
from @test cross apply strings.nodes('/ArrayOfString/string') as R(strings)
but that still leaves me with this
id string
-- ------
1 <string>Alpha</string>
1 <string>Alpha</string>
1 <string>Alpha</string>
2 <string>Bravo</string>
2 <string>Bravo</string>
Additionally, if I change the R.strings.query
to R.strings.value
to get rid of the tags, I get an error; XQuery [@test.strings.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'.
Can anyone point out what I'm missing in order to get each subsequent string value for each id on subsequent rows, and why the value() method is giving me that error?