8.4.3 SQL Server 2008XML应用
Microsoft SQL Server 2000中就推出了与XML相关的功能,并Transact-SQL语言的有关命令中增加了关键字FOR XMLOPENXML,使开发人员可以通过编写Transact-SQL代码来获取XML流形式的查询结果,或者将XML文档格式的数据导入到数据库的基本表中。SQL Server 2005 不仅扩展了这些关于支持XML的功能,而且推出了一个支持XSD schema验证、基于XQuery的操作和XML索引的本地XML数据类型。SQL Server 2008在其之前版本支持XML功能的基础之上,做了许多新改进和补充来解决客户在存储和操纵数据库中XML数据时所面临的挑战,不仅程序员能够定义XML数据类型的变量、参数,创建处理XML类型数据的视图、触发器,还能够使用XQuery语言完成对XML文档结点的遍历和数据查询等。由于篇幅所限,本节只简单介绍在SQL Sever 2008环境中如何将数据库基本表中的数据导出为XML文档,以及如何将XML文档数据导入数据库的基本表。
1、基本表导出为XML文档
FOR XML是对标准SQL语言SELECT语句的扩展,数据库管理系统会根据FOR XML使用的模式,返回具有一定格式的XML文档片段以便不同应用程序或者用户之间进行数据交互。在SQL
Server 2008中使用带FOR XML子句的SELECT查询语句就可以从数据库基本表中获得XML数据,而FOR XML子句主要使用RAWPATH模式。
(1) 单张基本表的导出
为介绍方便,我们以第一章介绍的学生表(students)为例,并希望将这张学生表中的数据导出为XML文档格式的数据,则只要使用表8-7中第3行的SELECT语句即可。
8-7 将基本表数据导出为XML格式数据
序号
1
2
3
USE Students10_Mis
GO
SELECT  *  FROM Students  FOR XML RAW, ELEMENTS;
注意,表8-7中的第1行和第2行是指定SELECT语句操作的数据库,如果我们在前面已经使
用了这个命令,则后面的操作就可以不使用这两行命令了。因此,本节后面的例子中都不再出现这两行命令。
关键字RAW告诉SQL Server 2008这里使用的是RAW模式。RAW模式返回的XML文档片段有一个特点,即每个行元素(默认标签为<row>)是基本表对应的一条记录,行元素中的每个子元素分别包含学号、姓名等信息。ELEMENTS参数能使学号、姓名等信息以行元素的子元素形式返回;如果不使用,默认情况下SQL Server2008会以行元素的属性形式返回。
运行表8-7中的命令就得到如图8-10所示的查询结果。从右下角的结果窗口可以看出,查询所得的XML文档数据被挤在一个只有一个单元格的表格中。单击这个单元格即可打开一个新的XML文档显示窗口(如图8-11)。由于窗口大小的限制,这里只显示了基本表Students中两条记录对应的,由<row></row>标记的XML元素。仔细分析可以发现,这个窗口中显示的XML文档与表8-2XML非常相似,只是没有了根元素标记<Students></Students>,且所有的<Student>标记变成了<row></Student>标记变成了</row>
8-10 基本表导出为XML(1)
8-11 基本表导出为XML(2)
(2) 多张基本表的导出
如果要从多张相互参照的基本表中导出XML数据应该怎么办呢?这里仍然以第一章介绍的学生表(Students)、课程表(Courses)和成绩表(Reports)为例,我们希望导出一个包含学号(Sno)、姓名(Sname)、性别(Ssex),所修课程号(Cno)、课程名称(Cname)、课程学分(Credits)和成绩(grade)数据的XML文档,则我们可以使用下面的SELECT语句,并使用PATH模式。
8-8 将多个基本表数据导出为XML格式数据
序号
   
1
2
3
4
5
6
7
8
9
10
SELECT  S.Sno    AS "report/Student/Sno",
    S.Sname  AS "report/Student/Sname",   
    S.Ssex    AS "report/Student/Ssex",
    C.Cno    AS "report/Course/Cno",
    C.Cname  AS "report/Course/Cname",
    C.Credits  AS "report/Course/Credits",
    R.Grade  AS  "report/grade"
FROM dbo.Students AS S, dbo.Courses AS C, dbo.Reports AS R
WHERE S.sno =R.Sno AND C.Cno =R.Cno
FOR XML PATH(''), ROOT('reports');
值得注意的是,表8-8中从第1行至第10行的代码为一条完整的SELECT语句,它是第一章学习过的数据库查询语句SELECT的简单扩充。最后一行FOR XML PATH(''), ROOT('reports')是为XML而特别扩充的,它表示查询结果为XML格式,关键词PATH表示这里使用的是FOR XMLPATH模式,ROOT('reports')表示把默认的根元素设置为reportsreport/Student/SnoXPATH的一种路径表示法,表示的是report元素有个子元素Student,而Student下面又有个子元素Sno,且这个Sno就是我们要查询的数据。在SSMS的“新建查询”窗口中输入并执行上面的语句就得到表8-9所示的XML格式的数据(部分),这里只包含了王建平同学选修的两门课对应的,由<report></report>标记的XML元素。
8-9 多个基本表数据导出为XML文档数据(部分)
序号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<reports>
  <report>
    <Student>
      <Sno>S01 </Sno>
      <Sname>王建评</Sname>
      <Ssex></Ssex>
    </Student>
    <Course>
      <Cno>C01 </Cno>
      <Cname>英语 </Cname>
      <Credits>4</Credits>
    </Course>
    <grade>92</grade>
  </report>
  <report>
    <Student>
      <Sno>S01  </Sno>
      <Sname>王建评 </Sname>
      <Ssex></Ssex>
    </Student>
    <Course>
      <Cno>C03  </Cno>
      <Cname>数据库 </Cname>
      <Credits>2</Credits>
    </Course>
    <grade>84</grade>
  </report>
  ……
</reports>
2XML文档导入基本表
前面介绍了如何将数据库的基本表中数据导出为XML文档,下面则介绍如何把XML文档数据导入到SQL Server 2008数据库的基本表中。
(1) 向基本表中添加记录
假设数据库Students10_Mis中已经存在基本表Students且不存在学号为S07的学生记录,则只要在SSMS的“新建查询”窗口中书写如表8-10中的代码,就可以将以XML文当格式描述的学生记录(S07,邵宁军,,19,计算机)导入到基本表Students中。
8-10 XML文档数据导入基本表中
序号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DECLARE @myDoc XML
DECLARE @imyDoc INT
SET @myDoc = '
<Students>
    <Student>
        <Sno>S07</Sno>
        <Sname>邵宁军</Sname>
        <Ssex></Ssex>
        <Sage>19</Sage>
        <Dname>计算机</Dname>
    </Student>
</Students>'
EXECUTE SP_XML_PREPAREDOCUMENT @imyDoc OUTPUT, @myDoc
INSERT INTO Students
SELECT *
FROM OPENXML (@imyDoc, '/Students/Student', 1)
WITH(Sno char(5) 'Sno',
Sname varchar(50) 'Sname',
Ssex char(2) 'Ssex',
Sage char(2) 'Sage',
Dname char(2) 'Dname')
EXECUTE SP_XML_REMOVEDOCUMENT @imyDoc
这里简单介绍一下表8-10中各行命令的作用。
1行和第2行声明了两个变量,名称分别为“myDoc”和“imyDoc”,类型分别为XML和整型INT,“@”表示Transact-SQL变量。
3行到第12行是给变量mydoc赋值,其值为表8-10中第3行和第12行两个单引号之间的XML文档描述的。
13行和第22行是调用SQL SEVER 2008系统中的两个存储过程,且它们在运行中不仅指定使用第3-4行声明的两个变量,同时指定把SELECT命令从XML文档格式中查询到的,由sql sever 2008<Student></Student>标记的元素以一条记录的形式插入到已经存在的基本表Students中。
同样,在SSMS的“新建查询”窗口中输入以上代码并执行后,就完成将XML文档数据导入基本表的目的,且通过“SELECT * FROM Students”语句可以查看基本表Students中原有和新导入的数据。
(2) 新建基本表并添加记录
如果数据库Students10_Mis中不存在基本表Students,则只要在SSMS的“新建查询”窗口中书写如表8-11中的代码并执行,就可以实现在该数据库中创建一个新的基本表Students并将以XML文当格式描述的两条学生记录(<Student></Student>标记的元素)导入到这个新建的基本表中。
8-11 创建基本表并将XML文档数据导入
序号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
DECLARE @myDoc XML
DECLARE @imyDoc INT
SET @myDoc = '
<Students>
    <Student>
        <Sno>S01</Sno>
        <Sname>王建平</Sname>
        <Ssex></Ssex>
        <Sage>21</Sage>
        <Dname>自动化</Dname>
    </Student>
    <Student>
        <Sno>S02</Sno>
        <Sname>刘华</Sname>
        <Ssex></Ssex>
        <Sage>19</Sage>
        <Dname>自动化</Dname>
    </Student>
</Students>'
EXECUTE SP_XML_PREPAREDOCUMENT @imyDoc OUTPUT, @myDoc
SELECT * INTO Students
FROM OPENXML (@imyDoc, '/Students/Student', 2)
WITH(Sno char(5) 'Sno',
Sname varchar(50) 'Sname',
Ssex char(2) 'Ssex',
Sage char(2) 'Sage',
Dname char(2) 'Dname')
EXECUTE SP_XML_REMOVEDOCUMENT @imyDoc