SQL Server xml之浅谈,浅谈,浅浅谈
2010-04-23 11:40 huayifu 阅读(394) 评论(0) 收藏 举报最近接触了SQL Server中两个比较特殊的类型:image和xml,关于image的文章可以看这里。今天来说一说xml这个类型,由于是水平有限,只是浅谈,呵呵。
关于xml这个类型,还是看到csdn一篇贴子:关于简历数据库设计中教育经历的问题(地址忘记了,有兴趣的可以去搜一搜)。我把贴子的内容说一下:简历创建的时候不是有个教育经历这一块嘛,但是由于经历不固定,有人小学(小学还出来找工作。。。小学的都去当老板了。),有人初中,有人高中。。。所以不可能再一个表里面设计多个字段。这个问题的一般想法是建立专门教育经历表,每个教育经历写一条记录,通过主键和主表联接就可以了。但下面有个回复说:sql xml类型存储。于是很好奇,这个是什么?赶紧到数据库一看,还真有这个类型(以前一直拘泥于varchar,char类型)。网上一搜,又是铺天盖地。于是抽空便研究了这个类型,今天放到这里,以作记号。
1)XML类型数据的INSERT 和SELECT操作
首先是insert操作:

create table xml_test(xmltest xml)
declare @xml XML
set @xml='<root>
<edu>
<date_from>20060901</date_from>
<date_to>20100701</date_to>
<school>ecust</school>
</edu>
</root>'
insert into xml_test values(@xml)
select * from xml_test
drop table xml_test
存储在数据库字段是这样的。
<root>
<edu>
<date_from>20060901</date_from>
<date_to>20100701</date_to>
<school>ecust</school>
</edu>
</root>
然后就是查询了。

DECLARE @XML2 XML
SELECT @XML2 = xmltest FROM xml_test
SELECT DATE_FROM.value('.', 'NVARCHAR(100)') As DATE_FROM
,DATE_TO.value('.','NVARCHAR(100)') As DATE_TO
,SCHOOL.value('.','NVARCHAR(100)') As SCHOOL
FROM
(
Select
T.C.query('date_from') As DATE_FROM
,T.C.query('date_to') As DATE_TO
,T.C.query('school') As SCHOOL
From
@Xml2.nodes('/root/edu') As T(C)
)BT
查询结果是
DATA_FROM DATE_TO SCHOOL
20060901 20100701 ECUST
这只是一个简单的实例,相信你也能看出来,上面那个简历数据库如果运用xml类型是怎么样解决了吧。
2)批量处理

declare @xml XML
set @xml='<root>
<id>1</id>
<id>2</id>
<id>3</id>
</root>'
select * from users where id=
(
Select
T.ID.value('.', 'int') As ID
From
@xml.nodes('/root/id') as T(ID)
)
上面的意思,从users这个表里查询id是1,2,3的记录。
以前我解决此方法的办法是用charindex这个函数。不过用xml的话,是一个节点一个节点去读取的,相对来说要安全一些。
3)xml操作函数
大致可分为查询类,修改类和跨域查询类。
查询类包含query(),value(),exist()和nodes().
修改类包含modify().
跨域查询类包含sql:variable()和sql:column().
我这里只说一下query()这个函数。有关更详细的可以去google,或者SQL Server 2005中XML操作函数详解,你真的了解SQL Server XML吗?

declare @xml XML
set @xml='<root>
<testxml>
<id value=''3''>1</id>
<id>2</id>
<id>3</id>
</testxml>
</root>'
select @xml.query('/root/testxml')
--返回结果:
--<testxml><id value="3">1</id><id>2</id><id>3</id></testxml>
select @xml.query('/root/testxml/id[2]')
--返回结果:
--<id>2</id>
select @xml.query('//id')
--返回结果:<id value="3">1</id><id>2</id><id>3</id>
select @xml.query('/root/testxml/id[@value=''3'']')
--返回结果:<id value="3">1</id>
/*************当有命名空间的时候,这个函数也要声明命名空间************/
declare @xml2 XML
set @xml2='<lk:root xmlns:lk="http://www.12345.cn">
<lk:testxml>
<lk:id value=''3''>1</lk:id>
<lk:id>2</lk:id>
<lk:id>3</lk:id>
</lk:testxml>
</lk:root>'
--查询不到,没带命名空间
SELECT @xml2.query('/root/testxml');
--内嵌方式定义命名空间
SELECT @xml2.query('declare namespace lk="http://www.12345.cn";
/lk:root/lk:testxml');
--返回结果:
--<lk:testxml xmlns:lk="http://www.12345.cn">
-- <lk:id value="3">1</lk:id>
-- <lk:id>2</lk:id>
-- <lk:id>3</lk:id>
--</lk:testxml>
最后说一下,有好东西不能乱用,要根据实际情况实际处理,在综合性能,功能等多方面考虑再作打算。