在SQL Server等支持XML数据类型的数据库环境中,XML聚合与拆分是常见的数据处理需求。XML聚合指的是将多行普通数据拼接转换为结构化的XML字符串,而XML拆分则是将已有的XML数据解析为行形式的普通数据,两种操作在接口数据交互、批量数据处理场景中应用十分广泛。

XML聚合的实现技巧
XML聚合的核心是借助SQL的FOR XML PATH语法,将查询结果按照指定的XML结构进行拼接。我们可以通过指定PATH的参数来定义XML的根节点,同时结合列别名控制节点的名称。
基础聚合示例
假设我们有一张用户表User,包含Id和UserName两个字段,现在需要将表中所有用户数据聚合为一个XML字符串:
-- 创建测试表
CREATE TABLE User (
Id INT,
UserName NVARCHAR(50)
);
-- 插入测试数据
INSERT INTO User VALUES (1, '张三'), (2, '李四'), (3, '王五');
-- XML聚合查询
SELECT Id AS user_id, UserName AS user_name
FROM User
FOR XML PATH('user'), ROOT('users');
上述查询执行后,会返回如下结构的XML:
<users>
<user>
<user_id>1</user_id>
<user_name>张三</user_name>
</user>
<user>
<user_id>2</user_id>
<user_name>李四</user_name>
</user>
<user>
<user_id>3</user_id>
<user_name>王五</user_name>
</user>
</users>
自定义聚合结构
如果需要生成属性形式的XML节点,可以在列别名中使用@前缀来定义属性名:
SELECT Id AS '@id', UserName AS '@name'
FROM User
FOR XML PATH('user'), ROOT('users');
执行结果会变成属性形式的XML结构:
<users> <user id="1" name="张三" /> <user id="2" name="李四" /> <user id="3" name="王五" /> </users>
XML拆分的实现技巧
XML拆分需要借助SQL的xml数据类型方法以及cross apply操作符,将XML中的每个节点解析为独立的行数据。核心用到的nodes方法可以提取XML中符合指定路径的所有节点,value方法则可以获取节点的值或属性值。
拆分元素形式XML
针对前面生成的带子元素的XML,拆分代码如下:
-- 定义待拆分的XML变量
DECLARE @xml XML = '<users>
<user>
<user_id>1</user_id>
<user_name>张三</user_name>
</user>
<user>
<user_id>2</user_id>
<user_name>李四</user_name>
</user>
<user>
<user_id>3</user_id>
<user_name>王五</user_name>
</user>
</users>';
-- 拆分XML为行数据
SELECT
t.c.value('user_id[1]', 'INT') AS Id,
t.c.value('user_name[1]', 'NVARCHAR(50)') AS UserName
FROM @xml.nodes('/users/user') t(c);
执行上述查询后,会得到三行数据,分别对应XML中的三个user节点,还原为用户表的结构。
拆分属性形式XML
如果XML是属性形式的,拆分时需要在value方法中指定属性路径,用@前缀标识属性:
DECLARE @attrXml XML = '<users>
<user id="1" name="张三" />
<user id="2" name="李四" />
<user id="3" name="王五" />
</users>';
SELECT
t.c.value('@id', 'INT') AS Id,
t.c.value('@name', 'NVARCHAR(50)') AS UserName
FROM @attrXml.nodes('/users/user') t(c);
注意事项
- 使用
FOR XML PATH聚合时,如果列值为NULL,默认不会生成对应的XML节点,如需处理NULL值可以配合ISNULL函数给默认值。 - 拆分XML时,
value方法的第二个参数需要和目标字段的数据类型匹配,否则会出现类型转换错误。 - 如果XML结构比较复杂,包含多层嵌套,拆分时需要逐层使用
nodes方法提取对应层级的节点,再获取最终的值。
总结
SQL中的XML聚合和拆分操作依托于数据库内置的XML处理语法,不需要额外的函数扩展即可实现。聚合操作通过FOR XML PATH可以快速生成结构化的XML数据,拆分操作通过nodes和value方法可以高效解析XML为多行数据。掌握这两个技巧可以大幅提升SQL处理半结构化数据的能力,应对更多复杂的业务场景。