sql server中對xml進行操作


一、前言

SQL Server 2005 引入了一種稱為 XML 的本機數據類型。用戶可以創建這樣的表,它在關系列之外還有一個或多個 XML 類型的列;此外,還允許帶有變量和參數。為了更好地支持 XML 模型特征(例如文檔順序和遞歸結構),XML 值以內部格式存儲為大型二進制對象 (BLOB)。

用戶將一個XML數據存入數據庫的時候,可以使用這個XML的字符串,SQL Server會自動的將這個字符串轉化為XML類型,並存儲到數據庫中。

隨着SQL Server 對XML字段的支持,相應的,T-SQL語句也提供了大量對XML操作的功能來配合SQL Server中XML字段的使用。本文主要說明如何使用SQL語句對XML進行操作。(以上摘自Qi Fei's Blog

首先要明確一個基本原則,XML類型的數據之間以及XML類型與其它數據類型之間都是不能比較的,也就是說XML類型的數據不能出現在等號的任何一邊。

大致可分為查詢類,修改類和跨域查詢類。

查詢類包含query(),value(),exist()和nodes().

修改類包含modify().

跨域查詢類包含sql:variable()和sql:column().

二、創建XML自定義數據庫表

創建xml自定義表:以前在網上查的都是

declare @xmlDoc xml;

set @xmlDoc='<book id="0001">

<title>C Program</title>

<author>David</author>

<price>21</price>

</book>'  這樣的,但是這僅僅是學習,不能真正用在項目或實際中缺乏實踐性。因為很少有直接操作sql內存中的這些。

閑話少說,直接上SQL創建表語句

 1 --1、創建xml測試數據庫表Xml_Table  Author:Fly , Email:feifei12300@126.com
 2 use Fly_Test --測試數據庫
 3 go
 4 create table Xml_Table(ID  INT identity PRIMARY KEY, XmlData  XML);
 5 --2、插入測試數據
 6 insert into Xml_Table(XmlData) values
 7 ('<book id="0001">
 8 <title>SqlServer2005</title>
 9 <author>Fly</author>
10 <price>21</price>
11 </book>
12 ');
13 insert into Xml_Table(XmlData) values
14 ('<book id="0002">
15 <title>SqlServer2008</title>
16 <author>Fly</author>
17 <price>22</price>
18 </book>
19 ');
20 insert into Xml_Table(XmlData) values
21 ('<book id="0003">
22 <title>SqlServer2012</title>
23 <author>Fly</author>
24 <price>23</price>
25 </book>
26 ');
27 --3、查詢
28 select * from Xml_Table;

結果如圖:

三、對xml操作

對xml操作,也不做過多解析,如有不清晰的可以聯系我;Emil:feifei12300@126.com

需要注意的是給每個節點添加屬性或者添加節點的時候如果已經存在的會報錯,所以最好是先exist('你的條件')=0 一下;

 1 --4、對XML操作真正開始了
 2 --SQLServer2005 中對 XML 的處理功能顯然增強了很多,提供了 query(),value(),exist(),modify(),nodes()
 3 --查詢所有書的名稱及作者
 4 select XmlData.query('/book') as Title,XmlData.query('/book/author') as Author from Xml_Table;
 5 --顯然這不是我們想要的數據
 6 select XmlData.value('(/book/title)[1]','nvarchar(max)') as Title, 
 7     XmlData.value('(/book/author)[1]','nvarchar(max)') as Author from Xml_Table;
 8 --查詢數目編號為0001的書的信息
 9 select  XmlData.value('(/book/title)[1]','nvarchar(max)') as Title,
10     XmlData.value('(/book/@id)[1]','nvarchar(max)') as BookID from Xml_Table
11     where XmlData.value('(/book/@id)[1]','nvarchar(max)') = '0001';
12 --修改數目編號為0001 的價格為 11
13 update Xml_Table
14     set XmlData.modify('replace value of (/book[@id="0001"]/price/text())[1] with "11"');
15 --修改 所有的數目作者為Fly_12300
16 update Xml_Table
17     set XmlData.modify('replace value of (/book/author/text())[1] with "Fly_12300"')
18 --查看是否編號為0001的價格修改為11,且所有作者修改為Fly_12300
19 select  XmlData.value('(/book/price)[1]','nvarchar(max)') as Title,
20     XmlData.value('(/book/@id)[1]','nvarchar(max)') as BookID,
21     XmlData.value('(/book/author)[1]','nvarchar(max)') as Author from Xml_Table
22     where XmlData.value('(/book/@id)[1]','nvarchar(max)') = '0001';
23 --添加屬性  
24 update Xml_Table
25 set XmlData.modify('insert attribute isbn {"12300321"} into (/book)[1]');
26 --查看是否存在屬性isbn
27 select  XmlData.value('(/book/@isbn)[1]','nvarchar(max)') as isbn,
28     XmlData.value('(/book/@id)[1]','nvarchar(max)') as BookID from Xml_Table
29     where XmlData.value('(/book/@id)[1]','nvarchar(max)') = '0001';
30 --在編號為0001的添加子節點 category  為 Computer 的分類
31 update Xml_Table
32     set XmlData.modify('insert <category>Computer</category> before (/book[@id=0001]/author)[1]');
33 --查看是否添加了category節點
34 select  XmlData.value('(/book/category)[1]','nvarchar(max)') as category,
35     XmlData.value('(/book/@id)[1]','nvarchar(max)') as BookID,XmlData from Xml_Table
36     where XmlData.value('(/book/@id)[1]','nvarchar(max)') = '0001';
37 --刪除節點
38 update Xml_Table
39     set XmlData.modify('delete /book[@id=0001]/category');
40 --查看是否刪除了category節點
41 select  XmlData.value('(/book/category)[1]','nvarchar(max)') as category,
42     XmlData.value('(/book/@id)[1]','nvarchar(max)') as BookID,XmlData from Xml_Table
43     where XmlData.value('(/book/@id)[1]','nvarchar(max)') = '0001';
44 --nodes()  查詢 book的編碼
45 select ids.value('@id', 'varchar(max)'),ids.value('(title)[1]','nvarchar(max)') title from  Xml_Table 
46     CROSS APPLY XmlData.nodes('//book') as X(ids) ;
47 --exist()
48 select XmlData.value('(/book/@id)[1]','nvarchar(max)') as BookID
49     from Xml_Table 
50     where XmlData.exist('(/book/@id)')=1 --判斷是否存在

如圖:

四、xml xpath

 1 create table Books(ID nvarchar(32) not null,Name nvarchar(64));
 2 insert into Books values ('0001','MSSQLServer2005'); --書名MSSQLServer2005
 3 insert into Books values ('0002','MSSQLServer2008'); --書名MSSQLServer2008
 4 insert into Books values ('0003','MSSQLServer2012'); --書名MSSQLServer2012
 5 --以下為xml   path
 6 SELECT ID,NAME FROM [dbo].[Books] FOR XML AUTO;
 7 SELECT ID,NAME FROM [dbo].[Books] FOR XML AUTO ,ELEMENTS ,ROOT('books');
 8 SELECT ID as 'BookID',NAME as 'BookName' FROM [dbo].[Books] FOR XML RAW;
 9 SELECT ID,NAME FROM [dbo].[Books] FOR XML RAW('book') ,ELEMENTS ,ROOT('books');
10 SELECT ID,NAME FROM [dbo].[Books] FOR XML PATH('') ;
11 SELECT ID as 'Detail/@ID',NAME as 'Detail/Name' FROM [dbo].[Books] FOR XML PATH('Book'), ROOT('Books');
12 SELECT STUFF((SELECT ';' + Name FROM [dbo].[Books] FOR XML PATH('')),1,1,'');

如圖:

五、跨域操作

 1 --根據Books 表中的ID,Xml_Table 表中的XmlData ID屬性  修改對應的 title屬性
 2 --即:根據在books中編碼0001的 的名稱 MSSQLServer2005
 3 --修改為Xml_Table表中book編碼為0001的title為 MSSQLServer2005
 4 
 5 declare @data xml
 6 declare @id nvarchar(36)
 7 declare @name nvarchar(64)
 8 declare custore_name cursor for 
 9 select Books.ID,Xml_Table.XmlData,Books.Name
10 from Books,Xml_Table
11     where Books.ID= Xml_Table.XmlData.value('(/book/@id)[1]','nvarchar(max)');
12  OPEN custore_name   
13 FETCH NEXT FROM custore_name into @id, @data, @name
14 WHILE(@@FETCH_STATUS=0)      
15  BEGIN      
16   set @data.modify(('replace value of (/book/title/text())[1] with sql:variable("@name")'))
17   update Xml_Table set XmlData = @data where XmlData.value('(/book/@id)[1]','nvarchar(max)') = @id   
18  FETCH NEXT FROM custore_name into   
19     @id, @data, @name
20  END    
21  CLOSE custore_name  
22  deallocate custore_name
23 
24  select * from Xml_Table

如圖所示:

 

六、結束語

需要注意點:添加、修改屬性或者節點需要先判斷是否存在(exist);跨域操作時使用了游標,不熟悉的可以自己查閱相關資料。

最后說明:轉載請注明出處

新手學習,高手忽略不計即可;

.net技術交流群:70895254

------------------------------2020-06-12新補充---------------------------------

七、常見錯誤

sql server xml.query()*屬性可能不會出現在元素之外。

使用.value,代替.query:

‘value()’需要一個單例(或空序列),可以找到‘xdt:untyped原子’類型的操作數*“

select distinct x.m.value('@ProductID','varchar(max)') as ProductID,
x.m.value('@Name','varchar(max)') as Name,
x.m.value('@URL','varchar(max)') as url 
from [表名] as s
outer apply s.data.nodes('/Object') as x(m)
where SchemaType='Permissions' and x.m.value('@ProductID','varchar(max)')<>'' and x.m.value('@URL','varchar(max)')<>''
GO

注意:表名后需要跟別名 outer apply  別名.列名.nodes('/xml包名') xml別名(列別名),查詢用 xml別名.列別名.value('@xml內列','varchar(max)')

xml實例:

<Object ProductID="CE8490C5-6EF8-4396-9C8C-9EFBA2484EB9" SchemaType="Permissions" ID="0000d80d-c13b-4ee2-b9e6-b63a174e604e" Name="分紅方案清單" DisplayName="分紅方案清單" Comment="S_AHR_61015867" URL="http://www.baidu.com" OtherURL="" TCode="S_AHR_61015867" CodeName="S_AHR_61015867_EMP310" SAPInstanceId="" />

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM