在 SQL 服务器中使用 FOR XML AUTO 时:如何在 LEFT OUTER JOIN 时从嵌套元素中删除空元素
When using FOR XML AUTO in SQL Server: how do I remove empty elements from nested elements when LEFT OUTER JOIN'ing
[编辑]:添加了 RAW 测试和更好的示例代码
我需要为遗留应用程序 运行 SQL Server 2005 生成 XML,我希望使用 FOR XML
功能。
但是,当左外连接 returns null 时,我似乎无法摆脱空元素。
我在下面创建了一些测试数据。
我得到的结果(自动):
<n id="1" Name="test1">
<s SubName="sub1" />
<s SubName="sub2" />
</n>
<n id="2" Name="test2">
<s />
</n>
我得到的结果(RAW):
<row id="1" Name="test1" SubName="sub1" />
<row id="1" Name="test1" SubName="sub2" />
<row id="2" Name="test2" />
我想要的结果:
<n id="1" Name="test1">
<s SubName="sub1" />
<s SubName="sub2" />
</n>
<n id="2" Name="test2" />
测试代码:
IF OBJECT_ID('tempdb..#name') IS NOT NULL BEGIN DROP TABLE #name END
SELECT * INTO #name FROM (
SELECT 1 id, 'test1' Name UNION ALL
SELECT 2 id, 'test2' Name )t
IF OBJECT_ID('tempdb..#sub') IS NOT NULL BEGIN DROP TABLE #sub END
SELECT * INTO #sub FROM (
SELECT 1 id, 'sub1' SubName UNION ALL
SELECT 1 id, 'sub2' SubName )t
SELECT n.id
, n.Name
, s.SubName
FROM #name n
LEFT OUTER JOIN #sub s ON s.id = n.id
FOR XML AUTO
SELECT n.id
, n.Name
, s.SubName
FROM #name n
LEFT OUTER JOIN #sub s ON s.id = n.id
FOR XML RAW
@Kesse,检查 XML RAW
SELECT n.id
, n.Name
, s.SubName FROM #name n
LEFT OUTER JOIN #sub s ON s.id = n.id
FOR XML RAW
似乎子查询与 PATH 或 RAW 结合是最简单的答案。两者都能产生想要的结果:
路径:
SELECT n.id "@id"
, n.Name "@Name"
, (SELECT s.SubName "@SubName"
FROM #sub s WHERE s.id = n.id
FOR XML PATH('s'), TYPE
)
FROM #name n
FOR XML PATH('n')
原始文件:
SELECT n.id
, n.Name
, (SELECT s.SubName
FROM #sub s WHERE s.id = n.id
FOR XML RAW('s'), TYPE
)
FROM #name n
FOR XML RAW('n')
[编辑]:添加了 RAW 测试和更好的示例代码
我需要为遗留应用程序 运行 SQL Server 2005 生成 XML,我希望使用 FOR XML
功能。
但是,当左外连接 returns null 时,我似乎无法摆脱空元素。
我在下面创建了一些测试数据。
我得到的结果(自动):
<n id="1" Name="test1">
<s SubName="sub1" />
<s SubName="sub2" />
</n>
<n id="2" Name="test2">
<s />
</n>
我得到的结果(RAW):
<row id="1" Name="test1" SubName="sub1" />
<row id="1" Name="test1" SubName="sub2" />
<row id="2" Name="test2" />
我想要的结果:
<n id="1" Name="test1">
<s SubName="sub1" />
<s SubName="sub2" />
</n>
<n id="2" Name="test2" />
测试代码:
IF OBJECT_ID('tempdb..#name') IS NOT NULL BEGIN DROP TABLE #name END
SELECT * INTO #name FROM (
SELECT 1 id, 'test1' Name UNION ALL
SELECT 2 id, 'test2' Name )t
IF OBJECT_ID('tempdb..#sub') IS NOT NULL BEGIN DROP TABLE #sub END
SELECT * INTO #sub FROM (
SELECT 1 id, 'sub1' SubName UNION ALL
SELECT 1 id, 'sub2' SubName )t
SELECT n.id
, n.Name
, s.SubName
FROM #name n
LEFT OUTER JOIN #sub s ON s.id = n.id
FOR XML AUTO
SELECT n.id
, n.Name
, s.SubName
FROM #name n
LEFT OUTER JOIN #sub s ON s.id = n.id
FOR XML RAW
@Kesse,检查 XML RAW
SELECT n.id
, n.Name
, s.SubName FROM #name n
LEFT OUTER JOIN #sub s ON s.id = n.id
FOR XML RAW
似乎子查询与 PATH 或 RAW 结合是最简单的答案。两者都能产生想要的结果:
路径:
SELECT n.id "@id"
, n.Name "@Name"
, (SELECT s.SubName "@SubName"
FROM #sub s WHERE s.id = n.id
FOR XML PATH('s'), TYPE
)
FROM #name n
FOR XML PATH('n')
原始文件:
SELECT n.id
, n.Name
, (SELECT s.SubName
FROM #sub s WHERE s.id = n.id
FOR XML RAW('s'), TYPE
)
FROM #name n
FOR XML RAW('n')