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!

有帮助吗?

解决方案

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

其他提示

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)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top