SQL Server递归CTE后使用FOR XML PATH按层级生成嵌套XML
T-SQL 嵌套层级XML生成方案
你现有方案的问题是直接平铺所有节点,没有基于EPC和ParentEPC的父子关系逐层挂载子节点,用自下而上递归拼接XML的方式可以完美实现任意深度的嵌套结构,不需要硬编码层级数。
可直接复用的实现代码
代码直接基于你已经生成的#EPC_items临时表编写,不需要修改你之前的递归CTE逻辑:
;WITH XMLBuild AS ( -- 锚点成员:先处理所有没有子节点的叶子节点,生成自闭合Item标签 SELECT cur.EPC, cur.ParentEPC, cur.SerialEventId, (SELECT cur.[@ItemName] AS [@ItemName] FOR XML PATH('Item'), TYPE) AS ItemXML FROM #EPC_items cur WHERE NOT EXISTS (SELECT 1 FROM #EPC_items child WHERE child.ParentEPC = cur.EPC) UNION ALL -- 递归成员:从叶子节点向上逐层拼接父节点,将直接子节点的XML挂载到当前节点下 SELECT p.EPC, p.ParentEPC, p.SerialEventId, ( SELECT p.[@ItemName] AS [@ItemName], ( SELECT ItemXML FROM XMLBuild c WHERE c.ParentEPC = p.EPC FOR XML PATH(''), TYPE ) FOR XML PATH('Item'), TYPE ) AS ItemXML FROM #EPC_items p WHERE EXISTS (SELECT 1 FROM XMLBuild c WHERE c.ParentEPC = p.EPC) -- 去重:避免已经处理过的节点重复参与递归 AND p.EPC NOT IN (SELECT ParentEPC FROM XMLBuild WHERE ParentEPC IS NOT NULL) ) -- 最终输出:取根节点(ParentEPC为NULL),外层包裹<Items>根标签 SELECT ( SELECT ItemXML FROM XMLBuild WHERE ParentEPC IS NULL -- 如果需要指定事件ID,放开下面这行注释即可 -- AND SerialEventId = 5557 FOR XML PATH(''), ROOT('Items'), TYPE ) AS ResultXML
关键说明
- 递归逻辑从最底层的叶子节点开始向上构建,每一层只关联直接下级节点,不会出现层级错位,支持任意深度的包装层级(比如托盘下有箱子,箱子下有盒子,盒子下有单品都可以正确生成)
- 所有XML片段都用
TYPE关键字标记为XML类型,避免特殊字符被转义 - 针对你给出的样例数据,上述代码生成的XML和你预期的结构完全一致,没有多余属性或层级
- 如果需要批量生成所有
SerialEventId对应的嵌套XML,只需要把最终查询和#SerialEvents表关联,按事件ID过滤即可
内容的提问来源于stack exchange,提问作者Phani
相关产品推荐
相关产品推荐

