Question

I'm trying to add a delimiter between the data that is being combined in a single column and having a lot of trouble trying to do so.

I'm working from a large XML file (8+ megs) and trying to get pieces of the data combined down to single columns for my database. The below query is doing this (sort of) but there is no separation of the data currently.

WITH XmlFile (Contents) AS (
SELECT CONVERT (XML, BulkColumn) 
FROM OPENROWSET (BULK 'C:\test.xml', SINGLE_BLOB) AS XmlData
)
SELECT c.value('(name)[1]', 'varchar(max)') AS [Name],
        c.value('(stuff)[1]', 'varchar(max)') AS [Stuff]       
FROM   XmlFile CROSS APPLY Contents.nodes ('(/root/item)') AS t(c)

test.xml file:

<root>
<item>
    <name>Something</name>
    <stuff>
        <note>Test 123</note>
        <note>Another Test</note>
    </stuff>
</item>
</root>

What it's returning:

enter image description here

Which is almost what I want! both note nodes have been merged into a single column... But I can't figure out howto add a delimiter between the values "Test 123 , Another Test"

Any help would be greatly appreciated!

Was it helpful?

Solution

you can use XQuery, something like this:

select
    c.value('(name)[1]', 'varchar(max)') as [Name],
    nullif(
      replace(
        c.query('
          for $i in stuff/note/text()
          return concat($i, ",")
         '
        ).value('.', 'nvarchar(max)') + ','
      ,',,','')
    , ',')
from @data.nodes ('/root/item') as t(c)

sql fiddle demo

OTHER TIPS

One solution:

/* testing setup */

declare @t xml = '<root>
<item>
    <name>Something</name>
    <stuff>
        <note>Test 123</note>
        <note>Another Test</note>
    </stuff>
</item>
<item>
    <name>Something else</name>
    <stuff>
        <note>Test 345</note>
        <note>Another 678</note>
    </stuff>
</item>
</root>';

declare @handle int
EXEC sp_xml_preparedocument @handle OUTPUT, @t


select 
P.n.value('(name/text())[1]', 'varchar(50)') as name,
stuff ((
SELECT 

       ', ' + D.n.value('(text())[1]', 'varchar(50)')
FROM   @t.nodes('/root/item') AS O(n)
CROSS APPLY O.n.nodes('stuff/note') AS D(n) 

Where P.n.value('(name/text())[1]', 'varchar(50)') = O.n.value('(name/text())[1]', 'varchar(50)')
for xml path('')), 1, 2, '') as stuff
FROM   @t.nodes('/root/item') AS P(n)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top