T-SQL——关于XML类型
0. 将结果集转化为XML格式
- 测试数据
IF OBJECT_ID('tempdb..#tempStu') IS NOT NULL
BEGIN
DROP TABLE #tempStu;
END;
CREATE TABLE #tempStu
(
[Name] VARCHAR(4),
[SubjectName] VARCHAR(4),
[Scores] INT
);
INSERT INTO #tempStu
(
Name,
SubjectName,
Scores
)
VALUES
('张三', '语文', 90),
('李四', '语文', 100),
('王五', '语文', 80);
- FOR XML AUTO
- 表名作为节点名称
- 一行作为一个节点,字段列作为节点属性
--AUTO则默认节点的名称为表名称
SELECT * FROM #tempStu WHERE Name = '李四' FOR XML AUTO;
--结果:(这里使用的是临时表,前面的_x0023_是数据库默认生成的)
--<_x0023_tempStu Name="李四" SubjectName="语文" Scores="100" />
- FOR XML RAW
- 通过RAW() 参数设置节点名称,无参默认节点名称为row
- 一行作为一个节点,字段列作为节点属性
--无参默认的使用row作为节点名称
SELECT * FROM #tempStu FOR XML RAW
--结果:
--<row Name="李四" SubjectName="语文" Scores="100" />
--使用参数设置节点名称
SELECT * FROM #tempStu WHERE Name = '李四' FOR XML RAW('Stu');
--结果:
--<Stu Name="李四" SubjectName="语文" Scores="100" />
- ELEMENTS
- 一行作为一个父节点,每一个字段作为一个子节点
SELECT Name,
SubjectName,
Scores
FROM #tempStu
FOR XML AUTO, ELEMENTS;
-- --结果:
-- <_x0023_tempStu>
-- <Name>张三</Name>
-- <SubjectName>语文</SubjectName>
-- <Scores>90</Scores>
-- </_x0023_tempStu>
-- <_x0023_tempStu>
-- <Name>李四</Name>
-- <SubjectName>语文</SubjectName>
-- <Scores>100</Scores>
-- </_x0023_tempStu>
-- <_x0023_tempStu>
-- <Name>王五</Name>
-- <SubjectName>语文</SubjectName>
-- <Scores>80</Scores>
-- </_x0023_tempStu>
- FOR XML PATH
- 一行一个父节点,每一个字段作为一个子节点
- PATH() 参数为父节点名称,无参则父节点名称默认为row
- 可以认为是FOR XML RAW ,ELEMENT的快捷方法
SELECT Name,
SubjectName,
Scores
FROM #tempStu
FOR XML PATH
-- 结果:
-- <Student>
-- <Name>张三</Name>
-- <SubjectName>语文</SubjectName>
-- <Scores>90</Scores>
-- </Student>
-- <Student>
-- <Name>李四</Name>
-- <SubjectName>语文</SubjectName>
-- <Scores>100</Scores>
-- </Student>
-- <Student>
-- <Name>王五</Name>
-- <SubjectName>语文</SubjectName>
-- <Scores>80</Scores>
-- </Student>
- 创建根节点:ROOT
SELECT * FROM #tempStu FOR XML RAW('Stu'),ROOT('Students')
--结果:
-- <Students>
-- <Stu Name="张三" SubjectName="语文" Scores="90" />
-- <Stu Name="李四" SubjectName="语文" Scores="100" />
-- <Stu Name="王五" SubjectName="语文" Scores="80" />
-- </Students>
1. 列值拼接为字符串
即实现某一列的列值累加为字符串,这个需求的实现方法有多种,可以参考我之前的博文
这里通过使用FOR XML PATH('')和STUFF()函数实现列值的拼接
DECLARE @subjectStr VARCHAR(100);
WITH cteStudent AS
(
SELECT '张三' AS Name,'语文'AS SubjectName,90 AS Scores
UNION ALL
SELECT '张三' AS Name,'数学'AS SubjectName,90 AS Scores
UNION ALL
SELECT '李四' AS Name,'语文'AS SubjectName,100 AS Scores
UNION ALL
SELECT '李四' AS Name,'数学'AS SubjectName,100 AS Scores
UNION ALL
SELECT '王五' AS Name,'语文'AS SubjectName,80 AS Scores
)
,Temp AS
(
SELECT DISTINCT SubjectName FROM cteStudent
)
SELECT @subjectStr =STUFF((SELECT ','+SubjectName FROM Temp FOR XML PATH('')),1,1,'')
SELECT @subjectStr
--结果:
--数学,语文
2. 字符串转换为列值
将一串使用特定符号分隔的字符,转换为一个表值。
实现这个功能的方法很多,可以参考我之前的博文
这里我们通过XML类型和REPLACE()函数实现字符串的分裂
--需要
DECLARE @str VARCHAR(MAX)='1,2,3,4,';
DECLARE @xmlstr XML;
SET ARITHABORT ON;
SET @xmlstr=CONVERT(XML, '<root><v>'+REPLACE(@str, ',', '</v><v>')+'</v></root>');
--SELECT @xmlstr
DECLARE @tableVar TABLE (F1 VARCHAR(100))
INSERT INTO @tableVar
SELECT F1=N.v.value('.', 'varchar(100)') FROM @xmlstr.nodes('/root/v') N(v);
SELECT * FROM @tableVar;
--结果
F1
--
1
2
3
4
--因为待分裂的字符串结尾也有一个逗号,所以这里是空字符串
上述操作在实际开发是中可以简单的封装为一个表值函数,便于重复使用
CREATE FUNCTION dbo.funSplitStr
(
@str varchar(1000),--待分裂的字符串
@separator varchar(10)--字符串中分隔使用的符号,比如说','
)
RETURNS @tableVar TABLE
(
F1 VARCHAR(100)
)
AS
BEGIN
DECLARE @xmlstr XML;
--SET ARITHABORT ON;
SET @xmlstr = CONVERT(XML, '<root><v>' + REPLACE(@str, @separator, '</v><v>') + '</v></root>');
--SELECT @xmlstr;
INSERT INTO @tableVar
SELECT F1 = N.v.value('.', 'varchar(100)') FROM @xmlstr.nodes('/root/v') N(v);
RETURN;
END;
GO
--测试该函数
DECLARE @str VARCHAR(100)='1,2,3,4,'
DECLARE @separator VARCHAR(10)=','
SELECT * FROM dbo.funSplitStr(@str,@separator)
--结果
F1
-------
1
2
3
4
--空字符串
- 示例:分组求和,并将聚合字段值使用“,”保留在一起
---测试数据
DECLARE @test TABLE
(
[Name] VARCHAR(4),
[Subject] VARCHAR(4),
[Grade] INT
);
INSERT INTO @test
VALUES
('张三', '语文', 100),
('张三', '数学', 90),
('李四', '语文', 90),
('李四', '数学', 80),
('李四', '英语', 70);
SELECT * FROM @test
SELECT Name,
Subjects= STUFF( (SELECT ','+Subject FROM @test WHERE Name=T1.Name FOR XML PATH ('')),1,1,'') ,
SUM(Grade) AS TotalGrade
FROM @test AS T1
GROUP BY Name
--结果:
Name Subjects Grade
----- ---------------- -----
李四 语文,数学,英语 240
张三 语文,数学 190
3. 一些说明
现在开发中,除了配置文件使用XML,我已经很少有需要使用XML的地方了,
SQL Server2000中便存在XML类型,2005中扩展了一些针对XML的操作函数。
而在SQL Server2016中已经支持JSON了,添加了许多处理JSON的内置函数。
但是,通过SQL Server中的XML类型处理字符串是及其便利的,如上文中的将字符串串转为列值等。
其用处还体现在一些需要数据库动态生成SQL语句的地方,总而言之就是方便与构造一些字符串
这里在举一个例子,无实际的意义,但是可以扩展一下思维。
示例:数据库层面构造简单的JSON字符串
DECLARE @test TABLE
(
[Name] VARCHAR(4),
[Subject] VARCHAR(4),
[Grade] INT
);
INSERT INTO @test
VALUES
('张三', '语文', 100),
('张三', '数学', 90),
('李四', '语文', 90),
('李四', '数学', 80),
('李四', '英语', 70);
SELECT '['+STUFF((SELECT ',{"name":"'+Name+'","subject":"'+[Subject]+'","grade":"' +CAST(Grade AS VARCHAR(4))+'"}' FROM @test FOR XML PATH ('')),1,1,'') +']'
--结果:
-- [
-- {
-- "name": "张三",
-- "subject": "语文",
-- "grade": "100"
-- },
-- {
-- "name": "张三",
-- "subject": "数学",
-- "grade": "90"
-- },
-- {
-- "name": "李四",
-- "subject": "语文",
-- "grade": "90"
-- },
-- {
-- "name": "李四",
-- "subject": "数学",
-- "grade": "80"
-- },
-- {
-- "name": "李四",
-- "subject": "英语",
-- "grade": "70"
-- }
-- ]
参考
T-SQL——关于XML类型的更多相关文章
- Sql Server xml 类型字段的增删改查
1.定义表结构 在MSSM中新建数据库表CommunicateItem,定义其中一个字段ItemContentXml 为xml类型 2.编辑表数据,新增一行,发现xml类型不能通过设计器录入数据. 需 ...
- sql 返回xml类型的数据
1, 这中方式可以在Item节点上加一个Items节点作为所有item节点的父节点 SELECT Orders.OrderNumber , ( SELECT ProductID ...
- SQL Server XML数据解析
--5.读取XML --下面为多种方法从XML中读取EMAIL DECLARE @x XML SELECT @x = ' <People> <dongsheng> <In ...
- 批量处理sql 数据存入xml类型列
个人记录 需求:当表T1 ItemCode和表T2 ItemName的数据相等时,将表T2所对应的ID和ItemName列的数据分别存入表T1 CAOZUO字段的id元素和text元素的文本中. 下面 ...
- 答:SQLServer DBA 三十问之一: char、varchar、nvarchar之间的区别(包括用途和空间占用);xml类型查找某个节点的数据有哪些方法,哪个效率高;使用存储 过程和使用T-SQL查询数据有啥不一样;
http://www.cnblogs.com/fygh/archive/2011/10/18/2216166.html 1. char.varchar.nvarchar之间的区别(包括用途和空间占用) ...
- SQL Server XML转Table
前言 在SQL Server中有时候我们需要传人一个Table过去,然后可以在存储过程中批量更新,批量的获取相应数据. 但存储过程的参数是固定,所以这里我们可以变通的传人xml类型的参数,然后在存储过 ...
- (转)SQL对Xml字段的操作
T-Sql操作Xml数据 一.前言 SQL Server 2005 引入了一种称为 XML 的本机数据类型.用户可以创建这样的表,它在关系列之外还有一个或多个 XML 类型的列:此外,还允许带有变量和 ...
- SQL SERVER XML 学习总结
SQL SERVER XML 学习总结 最新的项目任务要做一个数据同步的功能,这些天都在做技术准备,主要是用到了微软的Service Broker技术,在熟悉使用该技术的同时,又用到了Sql s ...
- 【转】SQLServer XML类型
SQL Server从2005起开始支持xml类型,这个数据类型对于后期的改变非常有用.一对多的关系在后期变成了多对多的关系,XML类型就是一个不错的选择. 1.创建测试数据 创建表 --创建表,包含 ...
- SQL对Xml字段的操作
转:http://www.cnblogs.com/youring2/archive/2008/11/27/1342288.html T-Sql操作Xml数据 一.前言 SQL Server 2005 ...
随机推荐
- 【odoo】【知识杂谈】单一实例多库模式下定时任务的问题分析
欢迎转载,但需标注出处,谢谢! 背景: 有客户反应有个别模块下的定时任务没有正常执行,是否是新装的模块哪些有问题?排查后发现,客户是在一台服务器上跑着一个odoo容器,对应多个数据库.个别库的定时任务 ...
- 学习PHP中的目录操作
对于编程语言来说,文件和目录的操作是其最最基础的功能.就像我们日常中最常见的图片上传.文件上传之类的功能,都需要文件和目录操作的支持.今天我们先来简单地学习一下 PHP 中关于目录操作的一些类和函数. ...
- 3gcms-Flash幻灯片上传后图片模糊解决办法
很简单,不用纠结,直接修改admin/lib/action/FileAction.class.php 将 $upload->thumbMaxWidth='300'; //以字串格式来传,如果你希 ...
- Java基础系列(35)- 数组声明创建
数组声明创建 首先必须声明数组变量,才能在程序中使用数组.下面是声明数组变量的语法: dataType[] arrayRefVar; //首选的方法 或 dataType arrayRefVar[]; ...
- Jmeter系列(12)- 上传接口压测
step-1上传接口分析 上传接口源码分析:分析上传文件类型.有无大小限制.存放上传文件服务器 没有源码通过抓包工具,或者Chrome查看框架源代码 接口路径/uploadfile,接口请求POST, ...
- jmeter 脚本录制方式详解
关于jmeter脚本录制方式,主要分为第三方工具录制.jmeter本身代理方式录制以及人为手写脚本的三种方式.其中第三方工具录制主要有3种主流工具进行录制,badboy BlazeMeter ...
- VMware安装最新版CentOS7图文教程
https://blog.csdn.net/reticent_man/article/details/80732395 https://blog.csdn.net/q2158798/article/d ...
- genymotion从本地拖拽apk到模拟器失败,报错“An error occured while deploying the file……”-解决方案
前两篇已经讲过genymotion的安装了,但genymotion构建的安卓模拟器的界面比较简洁,什么软件都没.那么我们进行测试之前,先将需要测试的apk安装到模拟器中,一般来说,直接将apk文件从本 ...
- [转载]linux下配置mariadb支持中文
转载网址:http://www.cnblogs.com/vingi/articles/4302330.html 修改/etc/mysql/my.cnfOn MySQL 5.5 I have in my ...
- P7600-[APIO2021]封闭道路【堆,dp】
正题 题目链接:https://www.luogu.com.cn/problem/P7600 题目大意 给出\(n\)个点的一棵树,边有边权,对于每个\(k\)求去掉最小边权和的点使得每个点的度数都不 ...