SQL Server 生成嵌套 XML 时如何添加 student 节点?
数据小许
使用 FOR XML PATH 添加包装节点
将外层查询改为 FOR XML PATH('user'),再将课程子查询的列别名设为 [student/student_classes],可以生成所需的嵌套结构。
SELECT
b.id,
b.name,
(
SELECT a.class_name
FROM classes AS a
WHERE a.id = b.id
FOR XML PATH('student_class'), TYPE
) AS [student/student_classes]
FROM student AS b
FOR XML PATH('user'), ROOT('users');
查询沿用了原来的关联条件 a.id = b.id,前提是该条件确实能关联学生与课程。如果实际使用其他关联字段,需要相应调整。
各层节点如何生成
FOR XML PATH 可以通过列别名中的 / 表达 XML 层级。这个查询中:
- 外层
PATH('user')将每条学生记录生成为一个<user>节点。 ROOT('users')为整个结果添加<users>根节点。- 子查询的
PATH('student_class')将每条匹配的课程记录生成为一个<student_class>节点。 [student/student_classes]在课程 XML 外添加<student>和<student_classes>两层节点。
子查询中的 TYPE 需要保留。它使结果以 XML 类型嵌入外层,避免 XML 标记被转义为 <student_class> 等字符串文本。
生成结果示例
假设学生记录为 id = 123、name = abc,且有一条匹配的课程记录 class_name = xyx,结果如下,缩进仅用于展示:
<users>
<user>
<id>123</id>
<name>abc</name>
<student>
<student_classes>
<student_class>
<class_name>xyx</class_name>
</student_class>
</student_classes>
</student>
</user>
</users>
如果一个学生匹配多条课程记录,<student_classes> 下会生成多个 <student_class> 节点。
原查询需要注意的地方
原代码中的 AS student classes 含有空格,按当前写法不能作为完整的列别名。即使改成 [student classes],也无法表达目标中的嵌套层级。应使用 [student/student_classes],并配合外层 FOR XML PATH。
XML 元素名称区分大小写。原查询中的 RAW('USER') 和 ROOT('USERS') 会生成大写名称,因此示例查询使用小写的 'user' 和 'users'。
备注:内容仅供参考。
