本文将带您了解关于SQLServerForXMLPath的运用的新内容,另外,我们还将为您提供关于InsideSQLServer2005读书随笔-用ForXMLPath来聚合字符串类型、MSSQLSE
本文将带您了解关于SQLServer For XML Path的运用的新内容,另外,我们还将为您提供关于Inside SQLServer 2005 读书随笔-用For XML Path来聚合字符串类型、MS SQLSERVER SELECT FOR XML 中字符的限制问题、sql server for xml path、SQL Server FOR XML PATH 和 STUFF函数的用法的实用信息。
本文目录一览:- SQLServer For XML Path的运用
- Inside SQLServer 2005 读书随笔-用For XML Path来聚合字符串类型
- MS SQLSERVER SELECT FOR XML 中字符的限制问题
- sql server for xml path
- SQL Server FOR XML PATH 和 STUFF函数的用法
SQLServer For XML Path的运用
FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作。那么以一个实例为主.
一.FOR XML PATH 简单介绍
那么还是首先来介绍一下FOR XML PATH ,假设现在有一张兴趣爱好表(hobby)用来存放兴趣爱好,表结构如下:
接下来我们来看应用FOR XML PATH的查询结果语句如下:
SELECT * FROM @hobby FOR XML PATH
结果:
<row> <hobbyID>1</hobbyID> <hName>爬山</hName> </row> <row> <hobbyID>2</hobbyID> <hName>游泳</hName> </row> <row> <hobbyID>3</hobbyID> <hName>美食</hName> </row>
由此可见FOR XML PATH 可以将查询结果根据行输出成XML各式!
那么,如何改变XML行节点的名称呢?代码如下:
SELECT * FROM @hobby FOR XML PATH('MyHobby')
结果一定也可想而知了吧?没错原来的行节点<row> 变成了我们在PATH后面括号()中,自定义的名称<MyHobby>,结果如下:
<MyHobby> <hobbyID>1</hobbyID> <hName>爬山</hName> </MyHobby> <MyHobby> <hobbyID>2</hobbyID> <hName>游泳</hName> </MyHobby> <MyHobby> <hobbyID>3</hobbyID> <hName>美食</hName> </MyHobby>
这个时候细心的朋友一定又会问那么列节点如何改变呢?还记的给列起别名的关键字AS吗?对了就是用它!代码如下:
SELECT hobbyID as 'MyCode',hName as 'MyName' FROM @hobby FOR XML PATH('MyHobby')
那么这个时候我们列的节点名称也会编程我们自定义的名称 <MyCode>与<MyName>结果如下:
<MyHobby> <MyCode>1</MyCode> <MyName>爬山</MyName> </MyHobby> <MyHobby> <MyCode>2</MyCode> <MyName>游泳</MyName> </MyHobby> <MyHobby> <MyCode>3</MyCode> <MyName>美食</MyName> </MyHobby>
SELECT '[ '+hName+' ]' FROM @hobby FOR XML PATH(''
没错我们还可以通过符号+号,来对字符串类型字段的输出格式进行定义。结果如下:
[ 爬山 ][ 游泳 ][ 美食 ]
那么其他类型的列怎么自定义? 没关系,我们将它们转换成字符串类型就行啦!例如:
SELECT '{'+STR(hobbyID)+'}','[ '+hName+' ]' FROM @hobby FOR XML PATH('')
好的 FOR XML PATH就基本介绍到这里吧,更多关于FOR XML的知识请查阅帮助文档!
接下来我们来看一个FOR XML PATH的应用场景吧!那么开始吧。。。。。。
二.一个应用场景与FOR XML PATH应用
首先呢!我们在增加一张学生表,列分别为(stuID,sName,hobby),stuID代表学生编号,sName代表学生姓名,hobby列存学生的爱好!那么现在表结构如下:
这时,我们的要求是查询学生表,显示所有学生的爱好的结果集,代码如下:
SELECT B.sName,LEFT(StuList,LEN(StuList)-1) as hobby FROM ( SELECT sName,(SELECT hobby+',' FROM student WHERE sName=A.sName FOR XML PATH('')) AS StuList FROM student A GROUP BY sName ) B
结果如下:
分析: 好的,那么我们来分析一下,首先看这句:
SELECT hobby+',' FROM student WHERE sName=A.sName FOR XML PATH('')
这句是通过FOR XML PATH 将某一姓名如张三的爱好,显示成格式为:“ 爱好1,爱好2,爱好3,”的格式!
那么接着看:
SELECT B.sName,' FROM student WHERE sName=A.sName FOR XML PATH('')) AS StuList FROM student A GROUP BY sName ) B
剩下的代码首先是将表分组,在执行FOR XML PATH 格式化,这时当还没有执行最外层的SELECT时查询出的结构为:
可以看到StuList列里面的数据都会多出一个逗号,这时随外层的语句:stuff(StuList,1,'')就是来去掉逗号,并赋予有意义的列明!
Inside SQLServer 2005 读书随笔-用For XML Path来聚合字符串类型
USE tempdb; GO IFOBJECT_ID('dbo.Groups') ISNOTNULL DROPTABLE dbo.Groups; GO CREATETABLE dbo.Groups ( groupid VARCHAR(10) NOTNULL, memberid INTNOTNULL, string VARCHAR(10) NOTNULL, val INTNOTNULL, PRIMARYKEY (groupid, memberid) ); INSERTINTO dbo.Groups(groupid, memberid, string, val) VALUES('a', 3, 'stra1', 6); INSERTINTO dbo.Groups(groupid, 9, 'stra2', 7); INSERTINTO dbo.Groups(groupid, val) VALUES('b', 2, 'strb1', 3); INSERTINTO dbo.Groups(groupid, 4, 'strb2', 5, 'strb3', 'strb4', 11); INSERTINTO dbo.Groups(groupid, val) VALUES('c', 'strc1', 8); INSERTINTO dbo.Groups(groupid, 7, 'strc2', 10); INSERTINTO dbo.Groups(groupid, 'strc3', 12); GO
表中数据内容:
groupid memberid string val
---------- ----------- ---------- -----------
a 3 stra1 6
a 9 stra2 7
b 2 strb1 3
b 4 strb2 7
b 5 strb3 3
b 9 strb4 11
c 3 strc1 8
c 7 strc2 10
c 9 strc3 12
现在要根据groupid来分组聚合string字段成类似于数组的形式:"stra1,stra2","strb1,strb2,strb3,strb4".....
传统的方法,不过貌似有点难想到:
Select groupid,Max(Casewhen rn=1then string else''End) +Max(Casewhen rn=2then','+string else''End) +Max(Casewhen rn=3then','+string else''End) +Max(Casewhen rn=4then','+string else''End) AS strs From (Select Groupid,string,ROW_NUMBER() over(partition by groupid orderby memberid) as rn From dbo.Groups) AS T groupby groupid go
groupid strs
---------- -------------------------------------------
a stra1,stra2
b strb1,strb4
c strc1,strc2,strc3
还有一中在后来被作者称为专用解决方案和完美解决案的查询:
SELECT groupid, STUFF((SELECT','+ string FROM dbo.Groups AS G2 WHERE G2.groupid = G1.groupid ORDERBY memberid FOR XML PATH('')), 1, '') AS string FROM dbo.Groups AS G1 GROUPBY groupid; GO
MSDN关于FOR XML PATH('')示例说法是:
由此可以得一个完美的查询方案。
MS SQLSERVER SELECT FOR XML 中字符的限制问题
采用sqlcommand返回单行的值这种方式查询的xml长度不能超过8000个字符。
ssql = "select * from " + tablename + " FOR XML AUTO,ELEMENTS";
sqlCommand command = new sqlCommand(ssql,connection);
resultXml = (string)sqlHelper.ExecuteScalar(connection,CommandType.Text,ssql);
查msdn发现
如果您使用 ExecuteReader 或 BeginExecuteReader 访问 XML 数据,sql Server 将以多行(每行 2,033 个字符)方式返回长度大于 2,033 个字符的所有 XML 结果。若要避免发生此行为,请使用 ExecuteXmlReader 或 BeginExecuteXmlReader 读取 FOR XML 查询。有关更多信息,请参见位于 http://support.microsoft.com/default.aspx?ln=zh-cn 上的 Microsoft 知识库中的文章 Q310378“PRB: XML Data Is Truncated When You Use sqlDataReader”(PRB:使用 sqlDataReader 时 XML 数据被截断)。
改为
1 ssql = "select * from " + tablename + " FOR XML AUTO,ELEMENTS";
2 sqlCommand command = new sqlCommand(ssql,connection);
3 System.Xml.XmlReader reader = command.ExecuteXmlReader();
4 reader.MovetoContent();
5 resultXml = reader.ReadOuterXml();
6
搞定。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jasonfqw/archive/2010/01/27/5261541.aspx
sql server for xml path
select * from s_login for xml path
可以用来 导出导入数据。
SQL Server FOR XML PATH 和 STUFF函数的用法
FOR XML PATH ,其实它就是将查询结果集以XML形式展现,将多行的结果,展示在同一行。
下面我们来写一个例子:
假设我们有个工作流程表:


CREATE TABLE [dbo].[Workflow_Action](
[WorkflowSchema] [nvarchar](128) NULL,
[ActionSchema] [nvarchar](128) NULL,
[ActionName] [nvarchar](64) NULL
)
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''material-price'',''confirm'',''审核通过'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''material-price'',''reject'',''审核驳回'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''material-price'',''executing'',''执行价格'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''material-price'',''non-executing'',''不执行价格'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''oa-meeting-apply'',''confirm'',''审核通过'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''oa-meeting-apply'',''reject'',''审核驳回'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''oa-officialSeal-apply'',''confirm'',''审核通过'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''oa-officialSeal-apply'',''reject'',''审核驳回'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''oa-officialSeal-apply'',''returned'',''归还公章'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase'',''commit'',''提交审核'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase'',''reject'',''采购驳回'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase'',''confirm'',''审核通过'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase'',''order'',''采购下单'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase'',''recommit'',''重新提交审核'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase'',''part-consignment'',''部分收货'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase'',''consignment'',''完成收货'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase-request'',''commit'',''提交审核'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase-request'',''confirm'',''审核通过'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase-request'',''reject'',''申请驳回'')
INSERT INTO [dbo].[Workflow_Action] ([WorkflowSchema],[ActionSchema],[ActionName]) VALUES (''purchase-request'',''recommit'',''重新提交审核'')
一、简单介绍
接下来,我们用这个方法查询这个表的数据。
select * from [dbo].[Workflow_Action] for xml path
它可以将查询结果转换为一段XML格式的代码

--for xml path 后面可以写东西,for xml path(Schema),这样写的话,可以将节点<row>变成<Schema>
select WorkflowSchema as WS,ActionSchema as SC,ActionName as AN from [dbo].[Workflow_Action] for xml path(''Schema'')

--我们还可以单独输出某一个字段的值
SELECT ''[ ''+ActionName+'' ]'' FROM [dbo].[Workflow_Action] FOR XML PATH('''')

二、实际应用
--我们看看一个操作对应的而多格流程
--一共是两层,里面一层查出单独的ActionName,拼成一行,然后使用where条件连接外层
SELECT WorkflowSchema,
(SELECT ActionName+'','' FROM [dbo].[Workflow_Action]
WHERE WorkflowSchema=A.WorkflowSchema --必须加的条件
FOR XML PATH('''')) AS ActionList
FROM [dbo].[Workflow_Action] A
GROUP BY WorkflowSchema

--where 连接条件必须要,如果去掉,就会查出所有的ActionName,如同上面示例一样

--现在我们优化一下格式,会发现最后多了一个‘,’符号,用LEFT函数去掉他,继续在外面接一层查询
select B.WorkflowSchema,
LEFT(B.ActionList,LEN(B.ActionList)-1) as ActionList
from (
SELECT WorkflowSchema,
(SELECT ActionName+'','' FROM [dbo].[Workflow_Action]
WHERE WorkflowSchema=A.WorkflowSchema
FOR XML PATH('''')) AS ActionList
FROM [dbo].[Workflow_Action] A
GROUP BY WorkflowSchema) as B

接下来,我们再讲一个其他的函数,实现同样的效果,STUFF函数。
sql stuff函数用于删除指定长度的字符,并可以在制定的起点处插入另一组字符。sql stuff函数中如果开始位置或长度值是负数,或者如果开始位置大于第一个字符串的长度,将返回空字符串。如果要删除的长度大于第一个字符串的长度,将删除到第一个字符串中的第一个字符。
一、作用
删除指定长度的字符,并在指定的起点处插入另一组字符。
二、语法
STUFF ( character_expression , start , length ,character_expression )
参数
character_expression 一个字符数据表达式。character_expression 可以是常量、变量,也可以是字符列或二进制数据列。
start 一个整数值,指定删除和插入的开始位置。如果 start 或 length 为负,则返回空字符串。如果 start 比第一个 character_expression 长,则返回空字符串。start 可以是 bigint 类型。
length 一个整数,指定要删除的字符数。如果 length 比第一个 character_expression 长,则最多删除到最后一个 character_expression 中的最后一个字符。length 可以是 bigint 类型。
返回类型
如果 character_expression 是受支持的字符数据类型,则返回字符数据。如果 character_expression 是一个受支持的 binary 数据类型,则返回二进制数据。
三、备注
1、如果开始位置或长度值是负数,或者如果开始位置大于第一个字符串的长度,将返回空字符串。如果要删除的长度大于第一个字符串的长度,将删除到第一个字符串中的第一个字符。
2、如果结果值大于返回类型支持的最大值,则产生错误。
四、sql stuff函数
--实例一
select STUFF(''abcdefg'',1,0,''1234'') --结果为''1234abcdefg''
select STUFF(''abcdefg'',1,1,''1234'') --结果为''1234bcdefg''
select STUFF(''abcdefg'',2,1,''1234'') --结果为''a1234cdefg''
select STUFF(''abcdefg'',2,2,''1234'') --结果为''a1234defg''
--实例二、SQL 将列转成字符串并用逗号分隔
--同样的,我们也用到了for xml path这个方法
SELECT STUFF((SELECT '','' + ActionName FROM [dbo].[Workflow_Action] FOR XML PATH('''')),1,1,'''') AS WA

--实例三、最后我们实现,上面for xml path的功能
--先查出两个字段,然后对ActionName这个字段进行转化,where条件记得加上,不加就会显示出所有的ActionName
select WorkflowSchema,
ActionName=(STUFF((select '','' + ActionName
from [dbo].[Workflow_Action] a
where a.WorkflowSchema=b.WorkflowSchema for xml path('''')),1,1,'''')) --where条件必须加上
from [dbo].[Workflow_Action] b group by WorkflowSchema

对比以上两种做法,可以自行比较哪种方式更加简便。
今天的关于SQLServer For XML Path的运用的分享已经结束,谢谢您的关注,如果想了解更多关于Inside SQLServer 2005 读书随笔-用For XML Path来聚合字符串类型、MS SQLSERVER SELECT FOR XML 中字符的限制问题、sql server for xml path、SQL Server FOR XML PATH 和 STUFF函数的用法的相关知识,请在本站进行查询。
本文标签: