针对xml列形成FOR XML查询以在root中包含属性

时间:2014-05-20 15:00:38

标签: sql xml tsql sql-server-2008-r2

给定一个包含xml列的表:

/*
CREATE TABLE #test (id int, content xml);
INSERT INTO #test VALUES (1, N'<i>abc</i>'),(1, N'<i>def</i>');
*/

我可以轻松地为下游反序列化创建一个xml文档:

  SELECT content AS [*]
    FROM #test T
 FOR XML PATH(''), ROOT('root')

得到以下特性:

/*
<root>
  <i>abc</i>
  <i>def</i>
</root>
*/

但是,我想在&#39; root&#39;中添加一个属性,其理想输出为:

/*
<root tag="42">
  <i>abc</i>
  <i>def</i>
</root>
*/

到目前为止,我所能完成的任务是为xml结构添加一个额外的级别:

  SELECT 42 AS [@tag],
         (SELECT content AS [*]  FROM #test T FOR XML PATH(''), TYPE) AS [*]
 FOR XML PATH('extra'), ROOT('root')

得到以下特性:

/*
 <root>
  <extra tag="42">
    <i>abc</i>
    <i>def</i>
  </extra>
</root>
*/

,因为

  SELECT 42 AS [@tag],
         (SELECT content AS [*]  FROM #test T FOR XML PATH(''), TYPE) AS [*]
 FOR XML PATH(''), ROOT('root')

是不允许的语法。 是否有任何建议在不添加额外级别的情况下向根节点添加属性?

1 个答案:

答案 0 :(得分:1)

嗯,答案现在看起来非常简单,但经过几次迭代才弄明白:

  SELECT 42 AS [@tag],
         (SELECT content AS [*]  FROM #test T FOR XML PATH(''), TYPE) AS [*]
 FOR XML PATH('root')

我没有意识到FOR XML语法可能会遗漏两者 ROOT和TYPE说明符,特别是因为这样做只会为原始查询产生一组片段。