转载网上的,方便以后查找
后续文章中的操作全部都针对该示例
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>
'
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 ] ' )
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
*/
/* 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()=
DECLARE @ElementName VARCHAR ( 20 )
SELECT @ElementName = ' title '
select @data .value( ' (/bookstore/book/*[local-name()=
sql:variable("@ElementName")])[1]
'
,
'
varchar(30)
'
)
/* output:
Everyday Italian
*/
/* output:
Everyday Italian
*/
- 映射为表结构查询
--将book元素映射到数据表book列
select Tab.Col.query('.') as book from @data.nodes('/bookstore/book')Tab(Col);
--查询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'
- 模糊查询
--
获取所有包含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)
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)
- 相邻节点查询
--
获取第一个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> */
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
*/
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属性值
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
*/
-- 获取第一个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)
-获取每本书的第一个author
select Tab.Col.value('author[1]','varchar(max)') as author
from @data.nodes('//book')as Tab(Col)
![](https://i-blog.csdnimg.cn/blog_migrate/bc19559f21abe67d3fdb1c32952de1b8.jpeg)
-- 获取所有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)
![](https://i-blog.csdnimg.cn/blog_migrate/883148ea4e6e7bab0eb0b18885807263.jpeg)
-- 获取不是日语(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)
![](https://i-blog.csdnimg.cn/blog_migrate/57edb727b31194751162e1e026870ea0.jpeg)
========模糊查询=========
--
查询第一个book节点的第一个属性值
SELECT @data .value( ' (/bookstore/book[1]/@*[position()=1])[1] ' , ' VARCHAR(20) ' )
/* output:
COOKING
*/
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>