FOR XML之RAW模式的程式碼實例詳解

黄舟
發布: 2017-03-22 17:03:13
原創
2232 人瀏覽過

描述:

raw模式將查詢結果集中的每一行轉換為帶有元素名稱的xml元素,將每一行的列轉換為row的屬性.

可以透過寫巢狀FOR XML查詢來產生XML層次結構

在預設情況下,所有非null值都會被對應為元素的屬性.

如果需要將查詢結果集中資料轉換為元素的子元素,需要使用elements指令.

語法:

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

具體參見範例:

建表Base,表格結構如下:

列名資料型別允許空
#idint允許
#bodynvarchar(50)允許

插入表格資料如下:

##body##123
#id
aaaa
#bbbb
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;
登入後複製

對於每個資料都是以元素顯示會讓人看起來很不舒服,如何修改元素名稱為其他名稱呢.

C.重新命名元素
/*
结果:
    <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指令的預設根元素為< 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(&#39;baseinfo&#39;),root(&#39;base&#39;),elements xsinil;
登入後複製

目前看起來,產生的xml結果似乎很不錯,但是,如果我們想要將資料庫中的body列改成xml的元素,該如何修改呢?

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資料型別進行傳回,舉例如下:建置學生表student,表結構如下:允許空允許
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模式的應用.
列名資料型別
sidint

namenvarchar(50)插入表格資料如下:id12
允許
#name
張三
李四############3######1K## ##########

建课程表sclass,表结构如下:

列名数据类型允许空
cidint允许
namenvarchar(50)允许

插入表数据如下:

idname
1语文
2数学
3英语

建student_class表,表结构如下:

列名数据类型允许空
sidint
cidint

插入数据如下:

cidsid
11
12
13
21
32
33

至此,数据结果是:

姓名课程
张三语文
张三数学
张三英语
李四语文
王五数学
王五英语

我们需要最后的结果形式如下:

姓名课程
张三语文,数学,英语
李四语文
王五数学,英语

该如何实现呢?

/*
结果:
    张三    语文,数学,英语
    李四    语文
    王五    数学,英语
*/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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板