raw模式将查询结果集中的每一行转换为带有<row>元素名称的xml元素,将每一行的列转换为row的属性.
可以通过编写嵌套FOR XML查询来生成XML层次结构
在默认情况下,所有非null值都将被映射为<row>元素的属性.
如果需要将查询结果集中数据转换为<row>元素的子元素,需要使用elements指令.
语法:
FOR XML
RAW [ ('ElementName') ]
[
<CommonDirectives>
[ , { XMLDATA | XMLSCHEMA [ ('TargetNameSpaceURI') ]} ]
[ , ELEMENTS [ XSINIL | ABSENT ]
] <CommonDirectives> ::=
[ , BINARY BASE64 ]
[ , TYPE ]
[ , ROOT [ ('RootName') ] ]
具体参见例子:
建表Base,表结构如下:
列名 | 数据类型 | 允许空 |
id | int | 允许 |
body | nvarchar(50) | 允许 |
插入表数据如下:
id | body |
1 | aaaa |
2 | bbbb |
3 | cccc |
4 |
例句:
A.返回查询数据的信息,使用for xml raw 模式
/*
结果:
<row id="1" body="aaaa" />
<row id="2" body="bbbb" />
<row id="3" body="dddd" />
<row id="4" />
*/select * from base for xml raw;
通过指定ELEMENTS指令使结果集以子元素的形式出现.
/*
结果:
<row>
<id>1</id>
<body>aaaa</body>
</row>
<row>
<id>2</id>
<body>bbbb</body>
</row>
<row>
<id>3</id>
<body>dddd</body>
</row>
<row>
<id>4</id>
</row>
*/select * from base for xml raw,elements;
我们注意到这个例句中没有将id为4的body显示出现.
原因是因为,在使用elements指令时,如果没有指定后面的命令,则默认使用abscent,此时不会为null值创建任何元素.
在下面的例句中通过使用elements xsinil可使null值显示在xml中.
B.同时指定elements指令和xsinil指令以生产null列值的元素
/*
结果:
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>1</id>
<body>aaaa</body>
</row>
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>2</id>
<body>bbbb</body>
</row>
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>3</id>
<body>dddd</body>
</row>
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>4</id>
<body xsi:nil="true" />
</row>
*/select * from base for xml raw,elements xsinil;
对于每条数据都是以<row>元素显示会让人看起来很不舒服,如何修改<row>元素名称为其他名称呢.
C.重命名<row>元素
/*
结果:
<baseinfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>1</id>
<body>aaaa</body>
</baseinfo>
<baseinfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>2</id>
<body>bbbb</body>
</baseinfo>
<baseinfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>3</id>
<body>dddd</body>
</baseinfo>
<baseinfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>4</id>
<body xsi:nil="true" />
</baseinfo>
*/select * from base for xml raw('baseinfo'),elements xsinil;
我们都知道,每个xml文件都有一个根元素,我们如何为这段xml文本加上它的根元素呢.
D.为for xml生成的xml指定根元素
可使用root指定,root指令的默认根元素为<root>
/*
结果:
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<baseinfo>
<id>1</id>
<body>aaaa</body>
</baseinfo>
<baseinfo>
<id>2</id>
<body>bbbb</body>
</baseinfo>
<baseinfo>
<id>3</id>
<body>dddd</body>
</baseinfo>
<baseinfo>
<id>4</id>
<body xsi:nil="true" />
</baseinfo>
</base>
*/select * from base for xml raw('baseinfo'),root('base'),elements xsinil;
目前看起来,生成的xml结果似乎很不错,但是,如果我们想要将数据库中的body列改成xml的<data>元素,该如何修改呢?
E.修改元素名
/*
结果:
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<baseinfo>
<id>1</id>
<data>aaaa</data>
</baseinfo>
<baseinfo>
<id>2</id>
<data>bbbb</data>
</baseinfo>
<baseinfo>
<id>3</id>
<data>dddd</data>
</baseinfo>
<baseinfo>
<id>4</id>
<data xsi:nil="true" />
</baseinfo>
</base>
*/select id,body data from base for xml raw('baseinfo'),root('base'),elements xsinil;
现在的结果,基本上符合一个xml的基本格式,那么,我们设想,如果不给id,body指定列名,也不指定根元素名,也不指定元素名,那会出现什么记过呢?
/*
结果:
1aaaa2bbbb3dddd4
*/
--因为id为int类型,为使id不出现列名,我们使id+0
--因为body为nvarchar类型,为使body不出现列名,我们使body+''select id+0,body+'' from base for xml raw(''), elements;
但是,对上面的结果,我们似乎无法分清楚每条数据,而且id为4的空值也没有显示出来,如何进行修改呢?见下句.
/*
结果:
1,aaaa;2,bbbb;3,dddd;4,null;
*/select id+0,',',isnull(body,'null')+'',';' from base for xml raw(''),elements;
如此以来,似乎看到了没有列名给我们带的好处.其实上句还可以再修改些.
/*
结果:
1,aaaa;2,bbbb;3,dddd;4,null;
*/select convert(nvarchar,id)+','+isnull(body,'null')+';' from base for xml raw(''),elements;
我们再来修改,让让结果以另一种方式出现.
/*
结果:
{1,aaaa}{2,bbbb}{3,dddd}{4,null}
*/select '{'+convert(nvarchar,id)+','+isnull(body,'null')+'}' from base for xml raw(''),elements;
现在可以看到,我们可以根据自己的需要进行组合,生成我们需要的结果.
在SQLServer2005中,已经支持了xml数据类型,因此,可以通过编写TYPE指令,将FOR XML查询的结果以xml数据类型进行返回,举例如下:
declare @string nvarchar(1000)declare @xml xml/*
消息257,级别16,状态3,第8行
不允许从数据类型xml到nvarchar的隐式转换。请使用CONVERT函数来运行此查询。
*/
--set @string=(select id,body from base for xml raw,type)set @xml=(select id,body from base for xml raw,type)
最后,以一个常用的例子来介绍for xml raw模式的应用.
建学生表student,表结构如下:
列名 | 数据类型 | 允许空 |
sid | int | 允许 |
name | nvarchar(50) | 允许 |
插入表数据如下:
id | name |
1 | 张三 |
2 | 李四 |
3 | 王五 |
建课程表sclass,表结构如下:
列名 | 数据类型 | 允许空 |
cid | int | 允许 |
name | nvarchar(50) | 允许 |
插入表数据如下:
id | name |
1 | 语文 |
2 | 数学 |
3 | 英语 |
建student_class表,表结构如下:
列名 | 数据类型 | 允许空 |
sid | int | |
cid | int |
插入数据如下:
cid | sid |
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
3 | 2 |
3 | 3 |
至此,数据结果是:
姓名 | 课程 |
张三 | 语文 |
张三 | 数学 |
张三 | 英语 |
李四 | 语文 |
王五 | 数学 |
王五 | 英语 |
我们需要最后的结果形式如下:
姓名 | 课程 |
张三 | 语文,数学,英语 |
李四 | 语文 |
王五 | 数学,英语 |
该如何实现呢?
/*
结果:
张三 语文,数学,英语
李四 语文
王五 数学,英语
*/select [name],
stuff(
(
select ','+[name]
from sclass
where cid in (
select cid
from student_class
where student.sid=student_class.sid
)
for xml raw(''),elements
),
1,1,'') sclassfrom student
以上就是FOR XML之RAW模式的代码实例详解的详细内容,更多请关注php中文网其它相关文章!
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
程序员必备接口测试调试工具:点击使用
Apipost = Postman + Swagger + Mock + Jmeter
Api设计、调试、文档、自动化测试工具
网页生成APP,用做网站的技术去做APP:立即创建
手机网站开发APP、自助封装APP、200+原生模块、2000+映射JS接口按需打包
相关文章
相关视频