设为首页 收藏本站
查看: 873|回复: 0

[经验分享] SQL Server 2005 XML 操作总结(转)

[复制链接]

尚未签到

发表于 2016-11-2 06:01:03 | 显示全部楼层 |阅读模式
  转载网上的,方便以后查找
  


后续
文章
中的操作全部都针对该示例


  


declare @data xml
set @data='
<bookstore>
<book category="COOKING" >
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="jp">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="WEB">
<title lang="cn">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
'



  

节点查询操作
  


  •  一般查询


--文档
select @data
/*output:
<bookstore>
<book category="COOKING">
......
</book>
</bookstore>
*/
--任意级别是否存在price节点
select @data.exist('//price')
/*output:
1
*/
--获取所有book节点
select @data.query('//book')
/*output:
<book category="COOKING">
......
</book>
<book category="CHILDREN">
......
</book>
<book category="WEB">
......
</book>
<book category="WEB">
......
</book>
*/
--获取第一个book节点
select @data.query('//book[1]')
/*output:
<book category="COOKING">
......
</book>
*/
--获取前两个book节点
select @data.query('//book[position()<=2]')
/*output:
<book category="COOKING">
......
</book>
<book category="CHILDREN">
......
</book>
*/
--获取最后一个book节点
select @data.query('//book[last()]')
/*output:
<book category="WEB">
......
</book>
*/
--获取price>35的所有book节点
select @data.query('//book[price>35]')
/*output:
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
……
</book>
<book category="WEB">
<title lang="cn">Learning XML</title>
……
</book>
*/
--获取category="WEB"的所有book节点
select @data.query('//book[@category="WEB"]')
/*output:
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
……
</book>
<book category="WEB">
<title lang="cn">Learning XML</title>
……
</book>
*/
--获取含category属性的所有book节点
select @data.query('/bookstore/book[@category]')
/*output:
<book category="COOKING">
......
</book>
<book category="CHILDREN">
......
</book>
<book category="WEB">
......
</book>
<book category="WEB">
......
</book>
*/
--获取book节点下title的lang="en"的所有title节点
select @data.query('//book/title[@lang="en"]')
/*output:
<title lang="en">Everyday Italian</title>
<title lang="en">XQuery Kick Start</title>
*/
--获取title的lang="en"且 price>35的所有book节点
select @data.query('//book[./title[@lang="en"] or price>35 ]')
/*output:
<book category="COOKING">
......
</book>
<book category="WEB">
......
</book>
<book category="WEB">
......
</book>
*/
--获取第一个book元素的title元素的值
select @data.value('(/bookstore/book/title)[1]', 'nvarchar(max)')
/*output:
Everyday Italian
*/
--获取title的lang="en"且 price>35的第一book的(第一个)title
select @data.query('//book[./title[@lang="en"] and price>35 ]')


              .value('(book/title)[1]','varchar(max)')
/*output:
XQuery Kick Start
*/
--等价于“获取title的lang="en"且 price>35的第一book的(第一个)title”
select @data.value('(//book[./title[@lang="en"] and price>35 ]/title)[1]','varchar(max)')
/*output:
XQuery Kick Start
*/





  • 根据节点名称查询


--查找第一个book节点的第一个名为title的节点的值
DECLARE @ElementName VARCHAR(20)
SELECT @ElementName = 'title'
select @data.value('(/bookstore/book/*[local-name()=


            sql:variable("@ElementName")])[1]','varchar(30)')
/*output:
Everyday Italian
*/





  • 映射为表结构查询

--将book元素映射到数据表book列
select Tab.Col.query('.') as book from @data.nodes('/bookstore/book')Tab(Col);
DSC0000.jpg --查询price元素的位置和值
SELECT a.number as position,b.price
FROM master.dbo.spt_values A
CROSS APPLY (
SELECT C.value('price[1]','float') as price
FROM @data.nodes('/bookstore/book[position()=sql:column("number")]')T(C)) b
WHERE A.type='P'

DSC0001.jpg



  • 模糊查询


--获取所有包含lang属性的节点
select @data.query('//*[@lang]')
/*output:
<title lang="en">Everyday Italian</title>
<title lang="jp">Harry Potter</title>
<title lang="en">XQuery Kick Start</title>
<title lang="cn">Learning XML</title>
*/
--获取所有book节点
select @data.query('/bookstore/*')
/*output:
<book category="COOKING">
......
</book>
<book category="CHILDREN">
......
</book>
<book category="WEB">
......
</book>
<book category="WEB">
......
</book>
*/
--获取所有节点
select @data.query('//*')
/*output:
<bookstore>
<book category="COOKING">
......
</book>
<book category="CHILDREN">
......
</book>
<book category="WEB">
......
</book>
<book category="WEB">
......
</book>
</bookstore>
*/
--获取所有包含属性的title节点
select @data.query('//title[@*]')
/*output:
<title lang="en">Everyday Italian</title>
<title lang="jp">Harry Potter</title>
<title lang="en">XQuery Kick Start</title>
<title lang="cn">Learning XML</title>
*/
--读取根节点的名称
SELECT @data.value('local-name(/*[1])','VARCHAR(20)') AS ElementName
/*output
bookstore
*/
--读取第三级上第一个节点的名称和值
SELECT @data.value('local-name((/*/*/*)[1])','VARCHAR(20)') AS ElementName,
@data.value('(/*/*/*/text())[1]','VARCHAR(20)') AS ElementValue
/*output
title Everyday Italian
*/
--读取第二级上第一个节点下属节点的名称和值
SELECT
C.value(
'local-name(.)','VARCHAR(200)') AS ElementName,
C.value(
'.','VARCHAR(200)') AS ElementValue
FROM @data.nodes('/*/*[1]/*') T(C)

 
DSC0002.jpg




  •  相邻节点查询


--获取第一个category=“WEB”的book节点的前一个book节点
select @data.query('(/bookstore/book[. << (/bookstore/book[@category="WEB"])[1]])[last()]')
/*output:
<book>
<title lang="jp">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
*/
--获取第一个category=“WEB”的book节点的前一个book节点
select @data.query('(/bookstore/book[. >>
(/bookstore/book[@category="WEB"])[1]])[1]
')
/*output:
<book category="WEB">
<title lang="cn">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
*/





  • 节点数目查询


--获得book节点的数量
SELECT @data.value('count(/bookstore/book)','INT')
/*output:
4
*/




 


属性查询操作
  
  


========一般查询=========
--获得第一个book节点的category属性值
select @data.value('(/bookstore/book/@category)[1]', 'nvarchar(max)')
/*output:
COOKING
*/
--获取title的lang="en"且 price>35的第一book的(第一个)title的lang属性
select @data.value('((//book[@category="WEB" and
price>35 ]/title)[1]/@lang)[1]
','varchar(max)')
/*output:
en
*/
--获取第一本书的title
select @data.value('(/bookstore/book[position()=1]/title)[1]','varchar(max)')
/*output:
Everyday Italian
*/



========根据属性名称查询========
--获取第一个book节点的名为category的属性值
DECLARE @att VARCHAR(20)
SELECT @att = 'category'
select @data.value('(/bookstore/book/@*[local-name()=sql:variable("@att")])[1]','VARCHAR(20)')
/*output:
COOKING
*/

========映射为表结构查询========

-获取每本书的第一个author
select Tab.Col.value('author[1]','varchar(max)') as author
    from @data.nodes('//book')as Tab(Col)


DSC0003.jpg

 


--获取所有book的所有信息
select
T.C.value(
'title[1]','varchar(max)') as title,
T.C.value(
'year[1]','int') as year,
T.C.value(
'price[1]','float') as price,
T.C.value(
'author[1]','varchar(max)') as author1,
T.C.value(
'author[2]','varchar(max)') as author2,
T.C.value(
'author[3]','varchar(max)') as author3,
T.C.value(
'author[4]','varchar(max)') as author4
from @data.nodes('//book') as T(C)


DSC0004.jpg


--获取不是日语(lang!="jp")且价格大于35的书的所有信息
select
T.C.value(
'title[1]','varchar(max)') as title,
T.C.value(
'year[1]','int') as year,
T.C.value(
'price[1]','float') as price,
T.C.value(
'author[1]','varchar(max)') as author1,
T.C.value(
'author[2]','varchar(max)') as author2,
T.C.value(
'author[3]','varchar(max)') as author3,
T.C.value(
'author[4]','varchar(max)') as author4
from @data.nodes('//book[./title[@lang!="jp"] and price>35 ]') as T(C)


DSC0005.jpg
 

 ========模糊查询=========



--查询第一个book节点的第一个属性值
SELECT @data.value('(/bookstore/book[1]/@*[position()=1])[1]','VARCHAR(20)')
/*output:
COOKING
*/


 
=========查询属性数量=========
--查询第一个book节点的属性数量
SELECT @data.value('count(/bookstore/book[1]/@*)','INT')
/*output:
1
*/








  

修改、删除、移动、遍历
  

========修改操作======

--将category="WEB"的第一个book节点的year值改为2000
set @data.modify('replace value of
(/bookstore/book[@category="WEB"]/year/text())[1] with "2000"
')
/*output:
<book category="WEB">
<title lang="cn">Learning XML</title>
<author>Erik T. Ray</author>
<year>2000</year>
<price>39.95</price>
</book>
*/
--替换第一个book节点的author的内容为“替换内容”
set @data.modify('replace value of(/bookstore/book[1]/author[1]/text())[1] with ("替换内容")')
/*output:
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>替换内容</author>
<year>2005</year>
<price>30.00</price>
</book>
*/
 ========删除操作========

--删除title的@lang="en"的所有book节点
set @data.modify('delete /bookstore/book[./title[@lang="en"]]')
/*output:
<bookstore>
  <book>
    <title lang="jp">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="WEB">
    <title lang="cn">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>
*/
--删除第一个book节点的author的内容
set @data.modify('delete /bookstore[1]/book[1]/author[1]/text()')
/*output:
  <book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author />
    <year>2005</year>
    <price>30.00</price>
  </book>
*/

========移动操作=========

--title="Harry Potter"的book节点在同级中上移一层
set @data.modify('insert (/bookstore/book[title="Harry Potter"])
before (/bookstore/book[. << (/bookstore/book[title="Harry Potter"])[1]])
[last()]
')
SET @data.modify ('delete /bookstore/book[title="Harry Potter"]
[. is (/bookstore/book[title="Harry Potter"])[last()]]
')
/*output:
<book category="CHILDREN">
......
</book>
<book category="COOKING">
......
</book>
<book category="WEB">
......
</book>
<book category="WEB">
......
</book>
*/
--title="Harry Potter"的book节点在同级中下移一层
set @data.modify('insert (/bookstore/book[title="Harry Potter"])
before (/bookstore/book[. >> (/bookstore/book[title="Harry Potter"])[1]])
[last()]
')
SET @data.modify ('delete /bookstore/book[title="Harry Potter"][1] ')
/*output:
<book category="COOKING">
......
</book>
<book category="WEB">
......
</book>
<book category="CHILDREN">
......
</book>
<book category="WEB">
......
</book>
*/
--title="Harry Potter"的book节点移到category为COOKING的book节点前
set @data.modify('insert (/bookstore/book[title="Harry Potter"])
before (/bookstore/book[@category="COOKING"])[1]
')
SET @data.modify ('delete /bookstore/book[title="Harry Potter"] [2]')
/*output:
<book category="CHILDREN">
......
</book>
<book category="COOKING">
......
</book>
<book category="WEB">
......
</book>
<book category="WEB">
......
</book>
*/
--title="Harry Potter"的book节点移到categroy为WEB的第一个book节点后
set @data.modify('insert (/bookstore/book[title="Harry Potter"])
after (/bookstore/book[@category="WEB"])[1]
')
SET @data.modify ('delete /bookstore/book[title="Harry Potter"][1] ')
/*output:
<book category="COOKING">
......
</book>
<book category="WEB">
......
</book>
<book category="CHILDREN">
......
</book>
<book category="WEB">
......
</book>
*/



========循环遍历所有元素=========

--循环所有book节点
DECLARE
   
@cnt INT,
   
@totCnt INT,
   
@child XML
-- counter variables
SELECT
   
@cnt = 1,
   
@totCnt = @data.value('count(/bookstore/book)','INT')
-- loop
WHILE @cnt <= @totCnt BEGIN
   
SELECT
       
@child = @data.query('/bookstore/book[position()=sql:variable("@cnt")]')
   
PRINT 'Processing Child Element: ' + CAST(@cnt AS VARCHAR)
   
PRINT 'Child element:  ' + CAST(@child AS VARCHAR(max))
   
PRINT ''
   
-- incremet the counter variable
    SELECT @cnt = @cnt + 1
END
/*output
Processing Child Element: 1
Child element:  <book category="COOKING">......</book>

Processing Child Element: 2
Child element:  <book><title lang="jp">......</book>


Processing Child Element: 3
Child element:  <book category="WEB">......</book>

Processing Child Element: 4
Child element:  <book category="WEB">......</book>

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-294379-1-1.html 上篇帖子: Sql Server存储过程分页总结 下篇帖子: sql server 树形结构的创建
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表