Sql server 具有多个子节点的Sql Server表到XML
我有下表Sql server 具有多个子节点的Sql Server表到XML,sql-server,xml,tsql,sql-server-2008,Sql Server,Xml,Tsql,Sql Server 2008,我有下表 name | age | misc ------------------ david | 20 | foo john | 30 | bar 我想将其转换为以下XML: <doc> <field name="name" val="david" /> <field name="age" val="20" /> <field name="misc" val="foo" /> </doc> <doc>
name | age | misc
------------------
david | 20 | foo
john | 30 | bar
我想将其转换为以下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>
这是我正在尝试做的一个示例,可以在SQLServerManagementStudio中运行。我找不到太多关于语法的文档,我对这些想法也很迷茫
感谢您的帮助
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>'
)
这个怎么样
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')
对于您的XQuery版本,请尝试以下操作:我刚刚删除了花括号,可以吗
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>'
)
您实际上是在尝试为未插入的数据获取XML。因此,首先获取一个唯一的行标识符,它不是一个字段,我将使用CTE和行号。从那里,您可以使用和: 根“ROOT”是添加一个简单的根元素,是对请求的xml格式的补充,但我认为它可能有用 更新 在仔细查看查询执行计划之后,您最好只创建格式化文本,然后转换为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')
我知道这是一个简单的语法问题!我想我更喜欢xquery版本,因为我认为它更明显地反映了正在发生的事情。再次感谢汉克斯的回答。如果我不能得到一个xquery解决方案,我正在考虑第二个版本,因为事实证明我只需要去掉大括号!unpivot看起来很有趣,可以很好地用于我需要的另一个查询!
;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')
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')