代码改变世界

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>

 

最后说一下,有好东西不能乱用,要根据实际情况实际处理,在综合性能,功能等多方面考虑再作打算。