首页  >  文章  >  后端开发  >  FOR XML之RAW模式的代码实例详解

FOR XML之RAW模式的代码实例详解

黄舟
黄舟原创
2017-03-22 17:03:132227浏览

描述:

raw模式将查询结果集中的每一行转换为带有2bef0154f7bc75ad48fa20d0234d078f元素名称的xml元素,将每一行的列转换为row的属性.

可以通过编写嵌套FOR XML查询来生成XML层次结构

在默认情况下,所有非null值都将被映射为2bef0154f7bc75ad48fa20d0234d078f元素的属性.

如果需要将查询结果集中数据转换为2bef0154f7bc75ad48fa20d0234d078f元素的子元素,需要使用elements指令.

语法:

FOR XML
RAW [ ('ElementName') ] 
    [ 
       <CommonDirectives> 
       [ , { XMLDATA | XMLSCHEMA [ (&#39;TargetNameSpaceURI&#39;) ]} ] 
       [ , ELEMENTS [ XSINIL | ABSENT ] 
    ] <CommonDirectives> ::= 
   [ , BINARY BASE64 ]
   [ , TYPE ]
   [ , ROOT [ (&#39;RootName&#39;) ] ]

具体参见例子:

建表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;

对于每条数据都是以2bef0154f7bc75ad48fa20d0234d078f元素显示会让人看起来很不舒服,如何修改2bef0154f7bc75ad48fa20d0234d078f元素名称为其他名称呢.

C.重命名2bef0154f7bc75ad48fa20d0234d078f元素

/*
结果:
    <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(&#39;baseinfo&#39;),elements xsinil;

我们都知道,每个xml文件都有一个根元素,我们如何为这段xml文本加上它的根元素呢.

D.为for xml生成的xml指定根元素

可使用root指定,root指令的默认根元素为4216313e5055da45c6d0ded129c5d644

/*
结果:
    <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(&#39;baseinfo&#39;),root(&#39;base&#39;),elements xsinil;

目前看起来,生成的xml结果似乎很不错,但是,如果我们想要将数据库中的body列改成xml的1d029f6197b5a3eb8a3fdf0a088ddf55元素,该如何修改呢?

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(&#39;baseinfo&#39;),root(&#39;base&#39;),elements xsinil;

现在的结果,基本上符合一个xml的基本格式,那么,我们设想,如果不给id,body指定列名,也不指定根元素名,也不指定元素名,那会出现什么记过呢?

/*
结果:
    1aaaa2bbbb3dddd4
*/
--因为id为int类型,为使id不出现列名,我们使id+0
--因为body为nvarchar类型,为使body不出现列名,我们使body+&#39;&#39;select id+0,body+&#39;&#39; from base for xml raw(&#39;&#39;), elements;

但是,对上面的结果,我们似乎无法分清楚每条数据,而且id为4的空值也没有显示出来,如何进行修改呢?见下句.

/*
结果:
    1,aaaa;2,bbbb;3,dddd;4,null;
*/select id+0,&#39;,&#39;,isnull(body,&#39;null&#39;)+&#39;&#39;,&#39;;&#39; from base for xml raw(&#39;&#39;),elements;

如此以来,似乎看到了没有列名给我们带的好处.其实上句还可以再修改些.

/*
结果:
    1,aaaa;2,bbbb;3,dddd;4,null;
*/select convert(nvarchar,id)+&#39;,&#39;+isnull(body,&#39;null&#39;)+&#39;;&#39; from base for xml raw(&#39;&#39;),elements;

我们再来修改,让让结果以另一种方式出现.

/*
结果:
    {1,aaaa}{2,bbbb}{3,dddd}{4,null}
*/select &#39;{&#39;+convert(nvarchar,id)+&#39;,&#39;+isnull(body,&#39;null&#39;)+&#39;}&#39; from base for xml raw(&#39;&#39;),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 &#39;,&#39;+[name]                    
from sclass                    
where cid in (                                    
select cid                                    
from student_class                                    
where student.sid=student_class.sid                                
)                    
for xml raw(&#39;&#39;),elements                
),            
1,1,&#39;&#39;) sclassfrom student

以上是FOR XML之RAW模式的代码实例详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn