PAYATHON 2026

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 标记被转义为 &lt;student_class&gt; 等字符串文本。

生成结果示例

假设学生记录为 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'。

备注:内容仅供参考。