Sql Server for XML with multiple child nodes

I have the following table

name  | age | misc
------------------
david | 20  | foo
john  | 30  | bar

And I want to convert it to the following XML:

<doc>
  <field name="name" val="david" />
  <field name="age" val="20" />
  <field name="misc" val="foo" />
</doc>
<doc>
  <field name="name" val="john" />
  <field name="age" val="30" />
  <field name="misc" val="bar" />
</doc>

I have below for one column for this work, however, if I try to add a second column for another fieldnode, I get an error:

Msg 9303, Level 16, State 1, Line 25
XQuery [query()]: Syntax error near 'name', expected '}'.

This is an example of what I'm trying to do and is ready to run in SQL Server Management Studio. I can not find much documentation on syntax and am pretty lost for ideas.

Any help is appreciated!

declare @MyData table (name varchar(200), age varchar(200), misc varchar(200))

insert into @MyData values('david', '20', 'foo')
insert into @MyData values('john', '30', 'bar')

/*This one works fine*/
SELECT (select * from @MyData as MyData for xml auto, type).query
(
' for $d in /MyData
   return 
   <doc>{
     <field name="name" val="{data($d/@name)}"  />
  }</doc>'
)

/*This one is what I want*/
SELECT (select * from @MyData as MyData for xml auto, type).query
(
' for $d in /MyData
   return 
   <doc>{
     <field name="name" val="{data($d/@name)}"  />
     <field name="age" val="{data($d/@age)}"  />
     <field name="misc" val="{data($d/@misc)}"  />
  }</doc>'
)
+3
source share
2 answers

How about this ..

select 
    (select 'name' as 'field/@name', a.name as 'field/@val' for xml path(''), type),
    (select 'age' as 'field/@name', a.age as 'field/@val' for xml path(''), type),
    (select 'misc' as 'field/@name', a.misc as 'field/@val' for xml path(''), type)
from 
    MyData a for xml path('doc')

for your version of XQuery try this: (I just removed the curly braces). This is normal?

SELECT (select * from @MyData as MyData for xml auto, type).query
(
' for $d in /MyData
   return 
   <doc>
     <field name="name" val="{data($d/@name)}"  />
     <field name="age"  val="{data($d/@age)}"  />
     <field name="misc" val="{data($d/@misc)}"  />
  </doc>'
)
+4
source

, XML . , , ( CTE row_number). UNPIVOT FOR XML EXPLICIT:

;with data as (
    select name, age, misc,
        row_number() over(order by name) as 'row'
    from @MyData
)
select 1 as tag,
       null as parent,
       row as [doc!1!row!hide],
       null as [field!2!name],
       null as [field!2!val]
from data
UNION
select 2 as tag,
       1 as parent,
       row as [doc!1!row!hide],
       fieldName as [field!2!name],
       val as [field!2!val]
from data d
  UNPIVOT(val for fieldName in (name, age, misc)) up
order by row, tag
FOR XML EXPLICIT, ROOT('root')

ROOT('root') XML-, , .

UPDATE
, , xml:

select cast('<field name="name" val="'+name+'" />'+
            '<field name="age" val="'+age+'" />'+
            '<field name="misc" val="'+misc+'" />'
            as xml)
from @MyData
for xml path('doc')
+1

Source: https://habr.com/ru/post/1781695/


All Articles