新概念SQL Server2005教程


目 录 第1章 数据库基础................................. 1 1.1 概述......................................................... 1 1.2 数据库模型............................................. 2 1.2.1 网状 ................................................ 2 1.2.2 层次型 ............................................ 2 1.2.3 关系型 ............................................ 3 1.3 数据库系统............................................. 3 1.3.1 数据库系统的用户......................... 4 1.3.2 数据库管理系统............................. 4 1.3.3 数据库管理系统的网络结构......... 5 1.4 关系型数据库......................................... 7 1.4.1 关系型数据库的定义..................... 7 1.4.2 关系数据库与表............................. 8 1.4.3 表的主键和外键............................. 9 1.4.4 数据完整性 .................................... 9 1.4.5 表的关联种类 .............................. 10 1.5 关系数据库的设计 ............................... 10 1.5.1 数据库设计过程........................... 10 1.5.2 关系数据库规范化....................... 11 1.6 课堂演练............................................... 12 1.6.1 图书和订单管理系统中表 的设计 .......................................... 12 1.6.2 公告信息系统中表的设计........... 13 1.7 小结....................................................... 14 1.8 课后练习............................................... 14 1.8.1 简答题 .......................................... 14 1.8.2 操作题...........................................14 第2章 初识SQL Server 2005...............15 2.1 SQL Server 2005简介 ...........................15 2.1.1 概述 ..............................................15 2.1.2 SQL Server 2005技术...................16 2.1.3 SQL Server 2005的新增功能.......17 2.2 SQL Server 2005版本及系统需求........20 2.2.1 SQL Server 2005的版本...............20 2.2.2 SQL Server 2005的硬件需求.......21 2.2.3 SQL Server 2005的软件需求.......22 2.2.4 网络软件.......................................23 2.2.5 Internet要求 ..................................25 2.3 SQL Server 2005的安装 .......................25 2.3.1 SQL Server的配置选项................25 2.3.2 从光盘直接安装...........................29 2.3.3 其他安装方式...............................35 2.3.4 从其他版本升级到 SQL Server 2005...........................37 2.4 SQL Server 2005的工具和实用工具 概述 .......................................................37 2.4.1 SQL Server Management Studio...38 2.4.2 Business Intelligence Development Studio......................41 2.4.3 Analysis Services ..........................42 新概念 SQL Server 2005 教程 2.4.4 SQL Server Configuration Manager 配置工具 ...................................... 42 2.4.5 性能工具 ...................................... 45 2.4.6 文档和教程 .................................. 48 2.5 管理SQL Server服务器 ........................ 49 2.5.1 管理服务器组 .............................. 49 2.5.2 注册服务器 .................................. 50 2.6 课堂演练............................................... 51 2.7 小结....................................................... 52 2.8 课后练习............................................... 52 2.8.1 简答题 .......................................... 52 2.8.2 操作题 .......................................... 52 第3章 数据库和表............................... 53 3.1 数据库存储结构................................... 53 3.1.1 数据库文件和文件组................... 53 3.1.2 页和区 .......................................... 54 3.1.3 事务日志 ...................................... 57 3.2 查看数据库........................................... 59 3.2.1 查看系统数据库........................... 59 3.2.2 查看用户数据库........................... 60 3.2.3 查看表之间的关系图................... 63 3.2.4 查看表的结构和内容................... 64 3.2.5 查看视图 ...................................... 66 3.2.6 查看存储过程 .............................. 67 3.2.7 查看用户和角色........................... 69 3.2.8 数据库架构 .................................. 72 3.3 数据库的建立和删除 ........................... 74 3.3.1 建立数据库 .................................. 74 3.3.2 删除数据库...................................77 3.3.3 数据库文件和文件组设置...........77 3.3.4 数据库大小估算和收缩数据库...79 3.4 表的建立、删除与修改 .......................81 3.4.1 新建表...........................................81 3.4.2 修改表的结构...............................82 3.4.3 建立表间的关联...........................82 3.4.4 删除表...........................................85 3.4.5 记录的新增和修改.......................87 3.5 课堂演练 ...............................................87 3.5.1 创建boarddb数据库......................87 3.5.2 创建boarddb数据库中的表..........87 3.6 小结.......................................................88 3.7 课后练习 ...............................................89 3.7.1 选择题和简答题...........................89 3.7.2 操作题...........................................89 第4章 账户和存取权限 ........................90 4.1 SQL Server的验证模式 ........................90 4.1.1 Windows验证模式 .......................90 4.1.2 混合验证模式...............................91 4.1.3 设置验证模式...............................92 4.2 账户和角色 ...........................................93 4.2.1 服务器的登录账户.......................93 4.2.2 数据库用户...................................96 4.2.3 角色 ............................................100 4.2.4 用户和角色的权限问题.............104 4.3 课堂演练 .............................................105 4.3.1 创建登录账户boardacc ..............105 4.3.2 设置boardacc用户的权限 ..........106 2 目 录 4.4 小结..................................................... 106 4.5 课后练习............................................. 107 4.5.1 选择题和简答题......................... 107 4.5.2 操作题 ........................................ 108 第5章 Transact-SQL及其程序 设计基础................................. 109 5.1 SQL语言 ............................................. 109 5.1.1 概述 ............................................ 109 5.1.2 SQL语言的分类......................... 110 5.2 Transact-SQL基础 .............................. 111 5.2.1 在SQL Server Management Studio 中执行SQL语句......................... 111 5.2.2 数据查询 .................................... 112 5.2.3 数据插入和删除......................... 115 5.2.4 数据修改 .................................... 117 5.2.5 使用函数 .................................... 117 5.2.6 使用公式 .................................... 117 5.2.7 数据库的操作语句..................... 118 5.2.8 表的操作语句 ............................ 120 5.3 Transact-SQL程序设计基础............... 122 5.3.1 标识符 ........................................ 122 5.3.2 数据类型 .................................... 125 5.3.3 运算符 ........................................ 138 5.3.4 变量 ............................................ 143 5.3.5 批处理 ........................................ 145 5.3.6 注释 ............................................ 146 5.3.7 控制流语句 ................................ 147 5.3.8 函数 ............................................ 153 5.4 课堂演练............................................. 156 5.4.1 在users表中插入记录.................156 5.4.2 显示打折后的书籍价格.............157 5.4.3 判断学生成绩及格与否.............157 5.5 小结.....................................................157 5.6 课后练习 .............................................158 5.6.1 简答题.........................................158 5.6.2 操作题.........................................158 第6章 提高检索效率的索引...............159 6.1 索引简介 .............................................159 6.1.1 创建索引的原因.........................160 6.1.2 建立索引应该考虑的问题.........161 6.2 索引类型 .............................................162 6.2.1 B-Tree索引结构 .........................162 6.2.2 聚集索引和非聚集索引.............163 6.2.3 唯一索引和组合索引.................166 6.3 创建索引 .............................................166 6.3.1 通过SQL Server Management Studio创建索引......................................166 6.3.2 使用SQL语言创建索引 .............168 6.3.3 创建索引的选项设置.................170 6.3.4 创建索引的空间考虑.................171 6.3.5 在视图和计算列上创建索引.....172 6.4 索引的查看和删除 .............................172 6.4.1 使用SQL Server Management Studio......................................................172 6.4.2 使用SQL语言.............................173 6.5 全文索引 .............................................173 6.5.1 SQL Server FullText Search服务174 6.5.2 创建全文目录.............................174 3 新概念 SQL Server 2005 教程 6.5.3 创建全文索引 ............................ 178 6.5.4 全文查询 .................................... 181 6.6 课堂演练............................................. 186 6.7 小结..................................................... 186 6.8 课后练习............................................. 187 6.8.1 选择题和简答题......................... 187 6.8.2 操作题 ........................................ 187 第7章 SQL高级使用 ......................... 188 7.1 SELECT高级查询 .............................. 188 7.1.1 数据汇总 .................................... 188 7.1.2 联接查询 .................................... 195 7.1.3 子查询 ........................................ 199 7.1.4 使用UNION运算符组合多个 结果 ............................................ 205 7.1.5 在查询的基础上创建新表......... 206 7.2 错误处理............................................. 206 7.2.1 使用@@ERROR全局变量处理 错误 ............................................ 207 7.2.2 使用RAISERROR ...................... 208 7.3 管理ntext、text和image数据.............. 209 7.3.1 检索ntext、text或image值......... 210 7.3.2 修改ntext、text或image值......... 213 7.4 事务处理............................................. 215 7.4.1 事务分类 .................................... 215 7.4.2 显示事务 .................................... 216 7.4.3 自动提交事务 ............................ 219 7.4.4 隐式事务 .................................... 220 7.4.5 分布式事务 ................................ 221 7.5 数据的锁定......................................... 223 7.5.1 并发问题.....................................223 7.5.2 事务的隔离级别.........................225 7.5.3 SQL Server中的锁定..................225 7.5.4 自定义锁.....................................228 7.6 使用游标 .............................................233 7.6.1 游标的概念.................................233 7.6.2 使用游标.....................................234 7.6.3 游标类型.....................................239 7.7 课堂演练 .............................................240 7.8 小结.....................................................241 7.9 课后练习 .............................................241 7.9.1 简答题.........................................241 7.9.2 操作题.........................................242 第8章 视图........................................243 8.1 概述.....................................................243 8.2 创建视图 .............................................244 8.2.1 使用SQL Server Management Studio管理平台创建视图 ..........245 8.2.2 使用SQL语句创建视图 .............247 8.3 使用视图 .............................................248 8.3.1 使用视图进行数据检索.............248 8.3.2 通过视图修改数据.....................249 8.4 视图的修改 .........................................250 8.4.1 修改视图.....................................250 8.4.2 重命名视图.................................251 8.5 视图信息的查询 .................................252 8.5.1 使用SQL Server Management Studio ..........................................252 8.5.2 使用sp_helptext存储过程 ..........253 4 目 录 8.6 视图的删除......................................... 254 8.6.1 使用SQL Server Management Studio.......................................... 254 8.6.2 使用Transact-SQL...................... 254 8.7 课堂演练............................................. 255 8.8 小结..................................................... 255 8.9 课后练习............................................. 255 8.9.1 选择题和简答题......................... 255 8.9.2 操作题 ........................................ 256 第9章 数据库完整性 ......................... 257 9.1 概述..................................................... 257 9.2 约束..................................................... 257 9.2.1 PRIMARY KEY约束 ................. 258 9.2.2 FOREIGN KEY约束.................. 258 9.2.3 UNIQUE约束 ............................. 259 9.2.4 CHECK约束............................... 260 9.2.5 列约束和表约束......................... 260 9.3 默认值................................................. 261 9.3.1 在创建表时指定默认值............. 261 9.3.2 使用默认值对象......................... 262 9.4 规则..................................................... 265 9.4.1 创建规则 .................................... 265 9.4.2 绑定规则 .................................... 266 9.4.3 删除规则 .................................... 267 9.5 存储过程............................................. 267 9.5.1 创建存储过程 ............................ 267 9.5.2 执行存储过程 ............................ 270 9.5.3 存储过程的参数......................... 271 9.5.4 存储过程的查看、修改和删除. 273 9.6 触发器.................................................274 9.6.1 创建触发器.................................275 9.6.2 inserted表和deleted表.................277 9.6.3 使用触发器.................................279 9.6.4 修改触发器.................................280 9.6.5 删除触发器.................................281 9.7 课堂演练 .............................................281 9.8 小结.....................................................282 9.9 课后练习 .............................................282 9.9.1 简答题.........................................282 9.9.2 操作题.........................................282 第10章 数据备份、恢复和报表 .........283 10.1 SQL Server备份概述 ........................283 10.2 备份数据 ...........................................284 10.2.1 备份设备...................................285 10.2.2 备份数据库...............................287 10.2.3 备份系统数据库.......................290 10.3 数据的恢复 .......................................290 10.3.1 自动恢复...................................290 10.3.2 恢复用户数据库.......................291 10.4 数据的导入和导出 ...........................293 10.5 Reporting Services.............................296 10.5.1 安装和配置Reporting Services ..................................................296 10.5.2 创建和设计报表.......................300 10.6 课堂演练 ...........................................305 10.6.1 备份boarddb数据库..................305 10.6.2 制作bookdb数据库中订单的 报表 ..........................................305 5 新概念 SQL Server 2005 教程 第12章 开发Web数据库....................339 10.7 小结................................................... 307 10.8 课后练习........................................... 307 12.1 概述...................................................339 10.8.1 选择题和简答题....................... 307 12.1.1 ASP和ASP.NET简介 ...............339 10.8.2 操作题 ...................................... 308 12.1.2 虚拟目录设置...........................340 第11章 使用VB开发SQL Server 应用程序............................. 309 12.2 使用ASP集成Web数据库.................343 12.2.1 一个简单的ASP网页................343 12.2.2 ASP内置对象 ...........................344 11.1 数据库应用程序开发概述 ............... 309 12.2.3 书籍信息查看系统...................347 11.2 ODBC概述........................................ 310 12.3 使用ASP.NET集成Web数据库........352 11.2.1 ODBC体系结构 ....................... 310 12.3.1 ASP.NET的虚拟目录设置.......352 11.2.2 配置ODBC数据源 ................... 311 12.3.2 ADO.NET连接数据库 .............353 11.3 OLE DB和ADO概述 ........................ 314 12.3.3 基于ASP.NET的书籍信息查看 系统 ..........................................354 11.3.1 OLE DB体系结构 .................... 315 11.3.2 ADO对象模型.......................... 316 12.4 课堂演练 ...........................................359 11.4 使用VB开发SQL Server应用程序... 318 12.5 小结...................................................360 11.4.1 ADO的引用和查看.................. 318 12.6 课后练习 ...........................................360 11.4.2 使用ADO Data控件开发简单的 数据库应用程序....................... 319 12.6.1 简答题.......................................360 12.6.2 操作题.......................................360 11.4.3 使用代码操纵数据库............... 325 附录A SQL语法符号的表示方法........361 11.5 课堂演练........................................... 337 11.6 小结................................................... 338 附录B SQL语法补充 .........................363 11.7 课后练习........................................... 338 附录C SQL Server的内置函数 ..........371 11.7.1 简答题 ...................................... 338 附录D 课后练习参考答案..................393 11.7.2 操作题 ...................................... 338 6 第 1 章 数据库基础 01 Chapter 本章导读: ” 数据库的特点 ” 数据库模型 ” 数据库管理系统 ” 数据库管理系统的网络结构 ” 关系型数据库的概念 ” 关系型数据库的规划 1.1 概述 计算机的出现,标志着人类开始使用机器来存储和管理数据。随着信息处理的发展, 计算机管理数据的方式也发生了巨大的变化。在20世纪50年代,出现了文件管理系统,即 以文件方式来管理及处理数据。但是,在数据量较大的系统中,数据之间存在这样或那样 的联系,如果仍然采用文件系统来管理这些数据,则处理这些数据就会引起很大的麻烦。 因此,在20世纪60年代,就出现了数据库管理系统。 从文件系统到数据库管理系统,标志着数据管理技术的飞跃。但是直到20世纪80年代, 数据库技术才得到真正的广泛应用。 与文件系统相比,数据库系统有以下特点: y 数据的结构化 在文件系统中,文件之间不存在联系。文件内部的数据一般是有 结构的,但是从数据的整体来说是没有结构的。数据库系统也包含许多单独的文 件,它们之间相互联系,在整体上也服从一定的结构形式,从而更适应管理大量 数据的需求。 y 数据共享 共享是数据库系统的目的,也是其最重要的特点。一个数据库中的数 据,不仅可以为同一企业或者组织内部的各部门共享,还可以被不同国家、地区 的用户所共享。 y 数据独立性 在文件系统中,文件和应用程序相互依赖,一方的改变总要影响另 一方的改变。数据库系统则力求使这种依赖性较小,以实现数据的独立性。 y 可控冗余度 数据专用后,每个用户拥有并使用自己的数据。许多数据就会出现 重复,这就是数据冗余。实现共享后,同一数据库中的数据集中存储,共同使用, 因而易于避免重复,减少和控制数据的冗余。 正是基于上述特点,数据库系统在数据处理中得到了很大的发展。其发展经历了3个阶 新概念 SQL Server 2005 教程 2 段:网状数据库、层次型数据库和关系型数据库。但是由于关系型数据库采用了人们习惯 使用的表格形式作为存储结构,易学易用,因而成为使用最广泛的数据库模型。现在常用 的数据库系统产品几乎全是关系型的,包括微软的SQL Server、IBM的DB2、ORACLE、 SYBASE、Informix等。另外,还有用于小型数据库管理的Access、FoxPro、PowerBuild。 1.2 数据库模型 数据库中的数据从整体来看是有结构的,即所谓数据的结构化。按照实现结构化所采 取的不同联系方式,数据库的整体结构可分为3种数据模型:网状、层次型和关系型。其中 前两类又称为格式化模型。 1.2.1 网状 网状数据库模型将每个记录当成一个结点,结点和结点之间可以建立关联,形成一个 复杂的网状结构,如图1.1所示。 图 1.1 网状结构模型 网状数据库模型的优点是避免了数据的重复性,缺点是关联性比较复杂,尤其是当数 据库变得越来越大时,关联性的维护会非常麻烦。 1.2.2 层次型 层次型数据库模型采用树状结构,依据数据的不同类型,将数据分门别类,存储在不 同的层次之下,如图1.2所示。 图 1.2 层次结构模型 层次型数据库模型的优点是数据结构类似金字塔,不同层次之间的关联性直接而且简 学号 课程号 得分 编号 姓名 职务 学号 姓名 性别 课程号 课程名 任课教师 分数 教师 学生 课程 系号 系名 系主任 编号 姓名 职务 专业代号 名称 课程号 课程名 学时学号 姓名 性别 系 专业 教师 学生 课程 第1章 Chapter 01 数据库基础 3 单。缺点是,由于数据纵向发展,横向关系难以建立,数据可能会重复出现,造成管理维 护的不便。 1.2.3 关系型 关系型数据库模型是以二维矩阵来存储数据的,行和列形成一个关联的数据表 (Table)。图1.3所示为一个图书的目录表。 图 1.3 关系型数据库中的表 如果要查找编号为“002”的图书的书名,则可以由横向的“002”与纵向的“书名” 字段的关联相交处而得到,如图1.4所示。 图 1.4 查找编号为“002”的图书的书名 由上面可看到,关系型数据库的关联是指表中行与列的关联,而网状数据库的关联是 记录与记录的关联。网状数据库只要存取一项数据,就需要将整笔记录取出,而关系型数 据库则可以直接存取到某一字段。 提 示 在关系型数据库中,如果有多个表存在,则表与表之间也会因为字段的关系而产生 关联。 1.3 数据库系统 一个数据库系统(Database System)可分为数据库(Database)与数据库管理系统 (Database Management System,DBMS)两个部分。简单地说,数据库即是一组经过计算 机整理后的数据,存储在一个或者多个文件中,而管理这个数据库的软件就称之为数据库 管理系统。 1.3.1 数据库系统的用户 数据库系统的用户是指使用和访问数据库中数据的人,有以下4种: 纵的一列称 为一个字段 横的一行称 为一个记录 新概念 SQL Server 2005 教程 4 y 数据库设计者 负责整个数据库系统的设计工作。设计者依据用户的需求设计合 适的表和格式来存放数据,并对整个数据库的存取权限作出规划。这些工作完成 后,即可交给数据库管理员进行管理。注意,这里的设计者一般并不只是指一个 人,而往往是指一组人。 y 数据库管理员 数据库管理员(Database Administrator,DBA)决定数据库中的数 据,并对这些数据进行修改、维护,监督数据库的运行状况。数据库管理员的任 务主要是决定数据库的内容,管理账户,备份和还原数据,以及提高数据库的运 行效率。 y 应用程序设计者 负责编写访问数据库的应用程序,使用户可以很友好地使用数 据库。可以使用Visual Basic、Visual C++、Delphi等来开发数据库应用程序。 y 普通用户 普通用户只需操作应用程序来访问所要查询的数据,不关心数据库的 具体格式及其维护和管理等问题。 在实际工作中,数据库管理员利用账户来控制每个用户的访问权限。每个用户都有自 己的账户和密码,使用此账户和密码,用户可以登录数据库,并在允许的权限范围内访问 数据库中的数据。 1.3.2 数据库管理系统 数据库管理系统(DBMS)是指帮助用户建立、使用和管理数据库的软件系统。它通 常有下面3个组成部分: y 数据描述语言(Data Description Language,DDL) 用来描述数据库的结构,供 用户建立数据库。 y 数据操作语言(Data Manipulation Language,DML) 供用户对数据库进行数据 的查询(数据的检索和统计等)和处理(数据的增加、删除和修改等)等操作。 y 其他管理和控制程序 包括安全、通信控制和工作日志等。 一般情况下,DDL和DML组成一个一体化的语言。对于关系型数据库,最常用的就是 SQL(Structure Query Language)语言,几乎所有的数据库管理系统都提供了对SQL语言的 支持。 注 意 不同的数据库管理系统,例如SQL Server和ORACLE,对SQL语言的功能扩展一般是 不相同的,但是一般的检索、删除及修改等操作都是一样的。 对DDL和DML,数据库管理系统都带有翻译程序,与普通高级语言类似,翻译程序也 可以分为编译执行和解释执行两种方式。如SQL语言,既有解释型,也有编译型。 数据库管理系统提供了用户和数据库之间的软件界面,使用户能更方便地操作数据库。 一般来说,它应有如下功能: y 数据定义 和高级语言类似,须定义需要的数据类型。 y 数据处理 DBMS必须提供用户对数据库的存取能力,包括记录的增加、修改、检 第1章 Chapter 01 数据库基础 5 索和删除等。 y 数据安全 管理和监督用户的权限,防止用户有任何破坏或者恶意的企图。 y 效率 DBMS应保证数据库的高效率运行,以提高数据检索和修改的速度。 提 示 一般DBMS提供的功能虽然完善,但并不是很好用,所以出现了数据库应用系统 (Database Application System,DBAS)。它是在DBMS支持下运行的一类计算机应用系统, 通常由数据库、应用程序和支持它们的DBMS组成。而应用程序就是由应用程序设计者使 用各种开发工具(例如上面提到的Visual Basic等)开发而成的。 1.3.3 数据库管理系统的网络结构 可依据数据的多少、使用的人数与硬件设备等条件,将数据库管理系统分为4种网络结 构:Main Frame大型数据库、本地小型数据库、分布式数据库和客户机/服务器数据库。下 面介绍这4种网络结构,并重点介绍客户机/服务器数据库。 1. Main Frame 大型数据库 大型数据库是由一台性能很强的计算机(称为主机或者数据库服务器)负责处理庞大 的数据,用户通过终端机与大型主机相连,以存取数据,如图1.5所示。 图 1.5 Main Frame 大型数据库 Main Frame大型数据库的所有检索和修改的功能都由主机来完成,因此,在有多人使 用时,主机会非常忙碌,使得反应比较缓慢。另外,大型主机的性能虽然很强,但价格都 相当昂贵,一般只有大型机构使用。 2. 本地小型数据库 在用户较少、数据量不大的情况下,可使用本地小型数据库。一般是由个人建立的个 人数据库。常用的DBMS有Access和Foxpro等。 3. 分布式数据库 分布式数据库就是为了解决Main Frame大型数据库反应缓慢的问题而提出的,它是由 多台数据库服务器组成。数据可来自不同的服务器,如图1.6所示。 用户端 用户端 用户端 大型数据库 新概念 SQL Server 2005 教程 6 图 1.6 分布式数据库 分布式数据库可以将数据分放在不同的服务器上,这样易于管理数据,而且其存取效 率也会比较高。 4. 客户机/服务器数据库 随着微机(微型计算机)的发展,其运算速度越来越快,而且价格低廉。在利用网络 将终端机(一般为微机)和数据库服务器连接后,就可以从数据库服务器中存取数据,而 且部分工作可以由终端机来完成,以分散数据库服务器的负担,这样数据库服务器就不必 是价格昂贵的大型主机了。这就是客户机/服务器数据库网络结构,如图1.7所示。 图 1.7 客户机/服务器结构 在客户机/服务器数据库的最简单形式中,数据库的处理可分成两个系统:客户机 (Client)和数据库服务器(Database Server),前者运行数据库应用程序,后者运行全部 或者部分数据库管理系统。在客户机上的数据应用程序(也称为前端系统)处理所有的屏 幕和用户输入/输出,在服务器上的后端系统处理和管理磁盘访问。例如,前端系统的一个 用户对数据库中的数据发出请求(也称为查询),前端应用程序就将该请求通过网络发送 给服务器,数据库服务器就进行搜索,并将用户查询所需的数据返回到客户机,图1.8表示 了客户机/服务器结构的工作方式。 数据库应用系统 客户机 数据库管理系统 服务器 查询请求 结果返回 用户端 用户端 用户端 数据库服务器 数据库服务器 LAN 用户端 用户端 用户端 数据库服务器 LAN 第1章 Chapter 01 数据库基础 7 图 1.8 客户机/服务器结构的工作方式 客户机/服务器结构的直接优点是很明显的:由于将处理工作分在两个系统上进行,在 网络上的流量将大大减少,可以加速数据的传输。 由于数据必须存放在一个单独的系统中,对于大公司来说可能是一个问题,因为他们 的数据库用户分散在很广的地理区域内,或者需要与其他部门或者中心主机共享部分的部 门数据库,这种情况就要求有一种方法能够将数据分布在各个主机上。客户机/服务器结构 下的网络流量比较小,因而可以使公司的局域网能轻松地访问远方的任何服务器。 1.4 关系型数据库 关系型数据库最大的特点在于它将每个具有相同属性的数据独立地存储在一个表中。 对任何一个表而言,用户可以新增、删除和修改表中的数据,而不会影响表中的其他数据。 它解决了层次型数据库的横向关联不足的缺点,也避免了网状数据库关联过于复杂的问题, 所以目前大部分的数据库都是使用关系型数据库模型。 1.4.1 关系型数据库的定义 关系型数据库概念是由IBM公司的E.F.Codd博士提出的,他在1976年6月发表的《关于 大型共享数据库数据的关系模型》论文中,首先阐述了关系数据库模型及其原理,并把它 用于数据库系统中。他指出,关系型数据库是指一些相关的表和其他数据库对象的集合。 这个定义表达了3部分含义: y 在关系数据库中,信息存放在二维表格结构的表中,一个关系数据库包含多个数 据表,每一个表包含行(记录)和列(字段)。一般来说,数据库都有多个表。 y 数据库所包含的表之间是有关联的,关联性由主键和外键所体现的参照关系实现。 y 数据库不仅包含表,还包含其他的数据库对象,例如视图、存储过程和索引等。 注 意 主键和外键的概念将在1.4.3小节中介绍。 E.F.Codd博士把数学法则引入到数据库领域中,使关系模型成为数学化模型。关系是 表的数学术语,表是一个集合。因此,数学中的集合论、数理逻辑等知识可以应用在关系 模型中,并可以使用这些知识进行数据库的规范化设计。 关系模型使用表格来表示和实现实体间的联系,而不像网状模型和层次模型,使用指 针链表来实现数据的联系。关系模型的数据结构简单灵活,容易掌握和使用。 新概念 SQL Server 2005 教程 8 1.4.2 关系数据库与表 关系数据库由多个表以及其他的数据库对象组成,表之间因为某些字段的相关性而产 生关联。例如,图1.9显示了一个图书数据库的3个表的结构及其关联。 图 1.9 图书数据库的 3 个表的结构及其关联 提 示 前面加有星号“*”的字段,表示是该表的主键(Primary Key),详见1.4.3小节。 图书表通过出版社编号与出版社表有关联,通过作者编号和作者表有关联。在实际分 析表的关联性时,一般都使用分割表的方法。即将所有需要的字段大致归类,使用正规化 分析方法将重复的字段选择出来,然后产生新的表。 从图1.9可以看到,关系型数据库有下面3个明显的优点。 1. 节省存储空间 因为数据库中会有大量的数据是重复的,如果每一次都要输入相同的数据,则容易浪 费磁盘空间。例如,在图1.10所示的表中,“人民邮电出版社”输入了3次,“国防工业出 版社”输入了2次,而作者字段中也有类似的重复情况。如果某一个表有成千上万笔记录, 则这些重复输入所造成的磁盘空间的浪费是很严重的。 图 1.10 一个重复输入的表 如果采用图1.9所示的方式,则只要在图书表中使用出版社和作者的编号,从而可节省 大量磁盘空间。 2. 可有效防止输入错误 如果重复数据太多,则在输入时难免会有输入错误。例如,出版社名称和作者姓名字 段,只要输错一个字,假设将编号为“002”的“国防工业出版社”输成“国方工业出版社”, 则在依据出版社名称查询时,该记录将会查不到。 如果按照图1.9的结构,则出版社名称只会输入一次,出错几率将大大降低。 第1章 Chapter 01 数据库基础 9 3. 方便数据修改 如果有一天,某出版社修改名称,在图1.10所示的表中,则对所有涉及到该出版社的 记录都要进行修改。而如果采用图1.9所示的结构,只需对出版社表修改一次就可以了。 1.4.3 表的主键和外键 键(Key)是关系数据库模型中的一个非常重要的概念。它是一个逻辑结构,不是数 据库的物理结构。下面仍然以如图1.9所示的数据库为例,来介绍表的主键(Primary Key) 和外键(Foreign Key)。 主键是指表中的某一列,该列的值唯一标识一行。例如,图书表中的图书编号字段, 对每一笔记录,它的值都是唯一确定的。给定一个图书编号,就能唯一确定表中的一笔记 录。而图书名称则不能作为主键,因为图书有可能是重名的。 主键实施实体完整性,即每个表必有而且仅有一个主键,主键必须唯一,而且不允许 为NULL或者重复。一般为整数类型的字段。 提 示 NULL表示该字段的值为空,它不是0,也不是空格。 外键是指表中含有的与另外一个表的主键相对应的字段,它用来与其他表建立关联。 例如,在图1.9所示的图书数据库中,图书表中的作者编号和出版社编号都是外键。因为作 者编号是作者表的主键,而出版社编号是出版社表的主键。 使用外键的优点是: y 提供表之间的连接。例如通过作者编号可将图书表和作者表连接起来。 y 可以根据外键的值检查输入数据的合法性。例如,在输入图书的数据时,应保证 输入的作者编号在作者表中存在,否则,数据库管理系统将报错。 y 保证了外键字段的值都是一个有效的主键,从而可以实施参照完整性。 可以将其视为主动画的子动画。 提 示 关系型数据库的表间关系,必须借助外键来建立。因为对某一个表的外键而言,其 详细数据是存储在另外一个表中的,因而称之为外键。 1.4.4 数据完整性 数据完整性(Data Integrity)是用来确保数据库中的数据的正确性和可靠性。例如,数 据库中某一个表的数据得到了更新,则所有与此相关的数据都要更新。例如,在图1.9所示 的图书数据库中,在输入图书表的记录时,应该保证所输入的出版社在出版社表中存在。 数据的完整性包括以下几类: y 实体完整性 实体完整性是为了保证表中的数据唯一,实体完整性可由主键来实 现。表中的主键在所有记录上的取值必须唯一。例如,图书表中,图书编号必须 唯一,以保证每一图书的唯一性。 新概念 SQL Server 2005 教程 10 y 域完整性 域完整性可以保证数据的取值在有效的范围内。例如,可以限制某一 字段的取值范围为300~500。若输入的内容不在此范围内,则不符合域完整性。 域完整性是对业务管理或者对数据库数据的限制,它们反映了业务的规则,因此 域完整性也称之为商业规则(Business Rule)。 y 参照完整性 参照完整性是用于确保相关联的表间的数据保持一致,避免因一个 表的记录修改,造成另一个表的内容变为无效的值。一般来说,参照完整性是通 过外键和主键来维护的。 y 自定义完整性 由用户自行定义的,不同于前面3种的完整性,也可以说是一种强 制数据定义。例如,在输入图书表的记录时,应确保图书编号不为空(NOT NULL)。 SQL Server 2005具有强制保证数据完整性的功能,以避免数据的错误。 1.4.5 表的关联种类 前面介绍了表的关联,在关系型数据库中,关联可分为如下3类: y 一对一关联 A表的一笔记录只能对应到B表中的一笔记录,称为一对一关联。实 际应用中,一对一的关联比较少。 y 一对多关联 A表的一笔记录可以对应到B表的多笔记录,而B表的一笔记录只能 对应A表的一笔记录时,称为一对多关联。例如,一本图书只能在一个出版社出版, 而一个出版社却可以出版多本图书。即在图书表中的一笔记录只对应出版社表中 的一笔记录,而出版社表中的一笔记录却对应图书表中的多笔记录。因此,出版 社表和图书表的关联即为一对多关联。 y 多对多关联 当两个表为多对多关联时,表示A表中的一笔记录能对应B表中的多 笔记录,而B表中的一笔记录也能对应A表中的多笔记录。例如,一个作者可以写 好几本书,而一本书也可以由多个作者来写。两者即为多对多关联。 1.5 关系数据库的设计 在使用普通文件的计算机应用系统中,数据是从属于程序的,数据文件的设计通常是 应用程序设计的一部分。在数据库系统应用中,数据由DBMS进行独立的管理,对程序的 依赖性大为减少。而数据库的设计也逐渐形成为一项独立的开发活动。 1.5.1 数据库设计过程 一般说来,数据库的设计都要经历需求分析、概念设计、实现设计和物理设计几个阶 段,图1.11所示为数据的设计过程和每一过程应生成的文档。 下面分别介绍各个模块的功能: y 需求分析 目的是分析系统的需求。该过程的主要任务是从数据库的所有用户那 里收集对数据的需求和对数据处理的要求,并把这些需求写成用户和设计人员都 能接受的说明书。 第1章 Chapter 01 数据库基础 11 图 1.11 数据库设计过程和产生的文档 y 概念设计 目的是将需求说明书中关于数据的需求,综合为一个统一的概念模型。 首先根据单个应用的需求,画出能反映每一应用需求的局部E-R模型。然后把这些 E-R模型图合并起来,消除冗余和可能存在的矛盾,得出系统总体的E-R模型。 提 示 E-R(Enity-Relation,实体-联系)模型是由美籍华人陈平山在1976年提出的,用来 建立数据库的概念模型。 y 实现设计 目的是将E-R模型转换为某一特定的DBMS能够接受的逻辑模式。对关 系型数据库,主要是完成表的关联和结构的设计。 y 物理设计 目的在于确定数据库的存储结构。主要任务包括:确定数据库文件和 索引文件的记录格式和物理结构,选择存取方法,决定访问路径和外存储器的分 配策略等。不过这些工作大部分可由DBMS来完成,仅有一小部分工作由设计人员 来完成。例如,物理设计应确定字段类型和数据库文件的长度。实际上,由于借 助DBMS,这部分工作难度比实现设计要容易得多。 对于一个程序编制人员,需要了解最多的应该是实现设计阶段。因为数据库不管设计 得好坏,都可以存储数据,但是在存取的效率上可能有很大的差别。可以说,实现设计阶 段是关系数据库存取效率的很重要的阶段。 1.5.2 关系数据库规范化 在实现设计阶段,常常使用E.F.Codd的关系规范化理论来指导关系数据库的设计。其 基本思想是,每个关系都应满足一定的规范,才能使关系模式设计合理,达到减少冗余, 提高查询效率的目的。 提 示 完全消除数据的冗余是不可能的,因为只要有关系存在,就会存在公共的属性。而 且,有时数据存在一定冗余可能更利于数据的管理和处理。 为了建立冗余较小、结构合理的数据库,Codd把关系应满足的规范划分为若干等级, 每一级称为一个范式。满足最低要求的称为第一范式(1NF);在1NF基础上又满足某些特 需求分析 概念设计 实现设计 物理设计 需求说明书 E-R模型 逻辑数据库结构 物理数据库结构 新概念 SQL Server 2005 教程 12 性的称为第二范式(2NF);在2NF的基础上再满足一些要求的为第三范式(3NF)。 以下是这些范式的定义: y 1NF 如果一个表R的每一个字段都是不可再分的,则称表R为第一范式。 y 2NF 若表R是1NF,而且它的每一非主键字段完全依赖于主键,则表R是第二范 式。 y 3NF 若表R是2NF,而且它的每一非主键字段不传递依赖于主键,则表R是第三 范式。传递依赖的含义是指经由其他字段而依赖于主键的字段。3NF的实际含义是 要求非主键字段之间不应该有从属关系。 实际上,范式就是施加于关系模式的约束条件。也是一个逐步对表结构进行规范化的 过程。 1.6 课堂演练 1.6.1 图书和订单管理系统中表的设计 建立图书和订单管理系统中的有关表。操作步骤如下: 分析包含的信息。对于图书和订单系统而言,应该包含图书的有关信息、作者的 有关信息、订单的有关信息和客户的有关信息。具体包括: y 图书信息 书名、作者、价格、出版社和简介等。 y 作者信息 作者姓名、电话和地址等。 y 订单 订购图书、订购数量、订单日期和客户等。 y 客户信息 客户姓名和客户地址。 上述信息确定后,就可以规划该系统应该包含的表。这里可以将其划分为4个表: y 图书表 book表。 y 作者表 authors表。 y 客户表 clients表。 y 订单表 orderform表。 确定每个表的字段。根据上面情况,可以确定每个表的名称和字段如下: y book表 图书编号、图书名称、作者编号、价格、出版社和简介。 y authors表 作者编号、姓名、电话和地址。 y clients表 客户编号、客户姓名、客户电话和客户地址。 y orderform表 订单编号、订购图书编号、订购数量、订购日期和订购客户编号。 确定主键。字段初步确定后,就需要为每个表确定一个主键。在上面的分析中, 可以看到,每个表的主键应该确定为每个表的编号,即通过编号可以唯一确定每一项记录。 确定外键。为了减少数据冗余,可以确定各表的外键如下: 第1章 Chapter 01 数据库基础 13 y book表 作者编号是外键,利用作者编号可以在authors表中确定作者的信息。 y authors表 不需要外键。 y clients表 不需要外键。 y orderform表 订购图书编号和订购客户编号是外键。通过前者可以在books表中确 定有关图书的信息;通过后者可以在clients表中确定客户的有关信息。 确定表之间的关联。经过前面的分析,表之间的关联也就很清楚了,如图1.12所 示。 图 1.12 表之间的关联 提 示 上述过程实际上是一个反复调整的过程。初步确定的表如果不满足要求,则可以重新 调整表结构,再进行分析。如此反复,直到满足要求为止。这里的要求就是兼顾数据的完 整性和易用性,又不要出现太多冗余。另外,在上面的过程中,如果要增加出版社的信息, 也可以增加一个出版社表。 1.6.2 公告信息系统中表的设计 这里针对一个简单的公告信息系统进行数据库设计。操作步骤如下: 该公告信息系统的主要功能是发布公告,系统首先验证用户是否合法,如果合法, 则将公告的内容保存到数据库中。因此,数据库中可以只包含两个表,一个用于验证用户, 一个用于保存公告信息。 分析两个表应包含的内容,具体如下: y 用户表 用户名、用户密码、用户姓名、性别、地址、E-mail和电话等。 y 公告信息表 公告编号、公告题目、公告内容、提交时间、提交用户名等。 确定每个表的字段,确定两个表的名称和字段如下: y users表 用户表,包含用户名、用户密码、用户姓名、性别、地址、E-mail和电话 字段。 y board表 公告编号、公告题目、公告内容、提交时间和提交用户名。 确定表之间的关联。由board表中的提交用户名,可以在users表中唯一确定用户的 详细信息。 新概念 SQL Server 2005 教程 14 1.7 小结 本章介绍了数据库系统的特点、数据库的3种模型、数据库系统的用户和数据库管理系 统,并着重介绍了关系型数据库的概念和有关的知识。 关系数据库的主键、外键以及数据完整性等概念,是进行下一步学习的基础,因此应 熟练掌握。另外,对于数据库设计和关系数据库的规范化,由于不是本书的主要内容,只 做了简单介绍,如想深入学习这方面的知识,可查阅相关的资料。 1.8 课后练习 1.8.1 简答题 (1)简要叙述数据库系统的特点。 (2)说明数据库模型的结构。 (3)说明数据库管理系统的网络结构。 (4)说明关系型数据库模型的基本概念。 1.8.2 操作题 (1)尝试做一个学生管理信息系统的数据库结构设计。 (2)尝试做一个网上图书商城的数据库结构的设计。 第 2 章 初识 SQL Server 2005 02 Chapter 本章导读: ” SQL Server 2005简介 ” SQL Server 2005特性和新增功能 ” SQL Server 2005软硬件需求 ” SQL Server 2005安装基本知识 ” SQL Server 2005安装 ” SQL Server 2005组件功能简介 ” SQL Server 2005配置工具 ” 管理SQL Server服务器 2.1 SQL Server 2005简介 Microsoft SQL Server起源于Sybase SQL Server。1988年,由Sybase公司、Microsoft公司 和Asbton-Tate公司联合开发的,运行于OS/2操作系统上的SQL Server诞生。后来,Asbton-Tate 公司退出SQL Server的开发,而Sybase公司和Microsoft公司签署了一项共同开发协议。在 1992年,两公司将SQL Server移植到了Windows NT操作系统上。之后,Microsoft致力于 Windows NT平台的SQL Server开发,而Sybase公司则致力于UNIX平台的SQL Server的开发。 在Microsoft SQL Server的发展历程中,有两个版本具有重要的意义。那就是在1996年 推出的SQL Server 6.5版本和在2000年8月推出的SQL Server 2000版本。6.5版本使SQL Server 得到了广泛的应用,而2000版本在功能和易用性上有了很大的增强,并推出了简体中文版, 它包括企业版、标准版、开发版和个人版4个版本。目前,SQL Server的最新版本是2005版 本,它扩展了SQL Server 2000的性能、可靠性、可用性、可编程性和易用性。SQL Server 2005 包含了多项新功能,这使它成为大规模联机事务处理(OLTP)、数据仓库和电子商务应用 程序的优秀数据库平台。 2.1.1 概述 Microsoft SQL Server 2005(以下简称SQL Server)由一系列相互协作的组件构成,能 满足最大的Web站点和企业数据处理系统存储和分析数据的需要 SQL Server提供了在服务器系统上运行的服务器软件和在客户端运行的客户端软件, 连接客户和服务器计算机的网络软件则由Windows NT/2000/2003系统提供。 SQL Server的数据库系统的服务器运行在Windows NT/2000/2003系统上,负责创建和 维护表以及索引等数据库对象,确保数据完整性和安全性,能够在出现各种错误时恢复数 新概念 SQL Server 2005 教程 16 据。 客户端应用程序可以运行在Windows 9x/NT/2000/2003/Vista系统上,完成所有的用户交 互操作。将数据从服务器检索出来后,可以生成副本,以便在本地保留以及对其进行操作。 提 示 客户/服务器(C/S)数据库计算是一种分布式的数据存储、访问和处理技术。它已成 为大多数企业计算的标准。Microsoft SQL Server是客户/服务器系统应用的完美例子。 SQL Server的客户/服务器提供了许多传统主机数据库所没有的先进功能。数据访问并 非局限于某些已有的主机数据库应用程序。SQL Server的一个主要优点就是与主流客户/服 务器开发工具和桌面应用程序的紧密集成。可以使用许多方法访问SQL Server数据库。例 如,可以在Visual Studio、Access、Power Builder和Delphi中访问SQL Server数据库。在进行 数据库应用程序开发时,可以使用数据访问对象(DAO)、远程数据对象(RDO)、ActiveX 控件、OLE DB、ODBC、DB-Library和其他第三方提供的开发工具访问SQL Server数据库。 SQL Server的客户端应用程序可以通过SQL Server提供的应用程序接口来访问服务器 端的数据。有4个主要的访问方法:ODBC API、OLE DB、Transact-SQL和DB-Library。对 于客户机,可以将这些API作为动态连接库来使用,并且通过客户端的网络库与SQL Server 服务器通信。 2.1.2 SQL Server 2005技术 Microsoft SQL Server 2005是用于大规模联机事务处理(OLTP)、数据仓库和电子商务 应用的数据库和数据分析平台。作为客户/服务器数据库系统,SQL Server 2005包含的技术 如下。 1. SQL Server 数据库引擎 数据库引擎是用于存储、处理和保护数据的核心服务。利用数据库引擎,可控制访问 权限并快速处理事务,从而满足企业内要求极高而且需要处理大量数据的应用需要。数据 库引擎还在保持高可用性方面提供了有力的支持。 SQL Server关系数据库引擎支持当今苛刻的数据处理环境所需的功能。数据库引擎充 分保护数据完整性,同时将管理上千个并发修改数据库的用户的开销减到最小。SQL Server 2005分布式查询使用户可以引用来自不同数据源的数据,就好像这些数据是SQL Server 2005数据库的一部分,同时分布式事务支持充分保护任何分布式数据更新的完整性。复制 同样使用户可以维护多个数据副本,同时确保单独的数据副本保持同步。可将一组数据复 制到多个移动的脱机用户,使这些用户自主地工作,然后将他们所做的修改合并回发布服 务器。 2. SQL Server Analysis Services Analysis Services为商业智能应用程序提供了联机分析处理(OLAP)和数据挖掘功能。 Analysis Services允许用户设计、创建以及管理其中包含从其他数据源(例如,关系数据库) 聚合而来的数据的多维结构,从而提供OLAP支持。对于数据挖掘应用程序,Analysis 17 第2章 Chapter 02 初识SQL Server 2005 Services允许使用多种行业标准的数据挖掘算法来设计、创建和可视化从其他数据源构造的 数据挖掘模型。 3. SQL Server Integration Services(SSIS) Integration Services是一种企业数据转换和数据集成解决方案,可以使用它从不同的源 提取、转换以及合并数据,并将其移至单个或多个目标。 4. SQL Server 复制 复制是在数据库之间对数据和数据库对象进行复制和分发,然后在数据库之间进行同 步以保持一致性的一组技术。使用复制可以将数据通过局域网、广域网、拨号连接、无线 连接和Internet分发到不同位置以及分发给远程用户或移动用户。 5. SQL Server Reporting Services(SQL Server 报表服务) Reporting Services是一种基于服务器的新型报表平台,可用于创建和管理包含来自关 系数据源和多维数据源的数据的表报表、矩阵报表、图形报表和自由格式报表。可以通过 基于Web的连接来查看和管理创建的报表。 6. SQL Server Notification Services(SQL Server 通知服务) Notification Services平台用于开发和部署可生成并发送通知的应用程序。Notification Services可以生成并向大量订阅方及时发送个性化的消息,还可以向各种各样的设备传递消 息。 7. SQL Server Service Broker Service Broker是一种用于生成可靠、可伸缩且安全的数据库应用程序的技术。Service Broker是数据库引擎中的一种技术,它对队列提供了本机支持。Service Broker还提供了一 个基于消息的通信平台,可用于将不同的应用程序组件链接成一个操作整体。Service Broker 提供了许多生成分布式应用程序所必需的基础结构,可显著减少应用程序的开发时间。 Service Broker还可帮助用户轻松自如地缩放应用程序,以适应应用程序所要处理的流量。 8. 全文搜索 SQL Server包含对SQL Server表中基于纯字符的数据进行全文查询所需的功能。全文查 询可以包括单词和短语,或者一个单词或短语的多种形式。 9. SQL Server 工具和实用工具 SQL Server提供了设计、开发、部署和管理关系数据库、Analysis Services多维数据集、 数据转换包、复制拓扑、报表服务器和通知服务器所需的工具。 2.1.3 SQL Server 2005的新增功能 SQL Server 2005与SQL Server 2000相比,在性能、功能、可靠性以及使用性等方面, 都得到了很大的扩展和增强。由于这些新功能,使得SQL Server 2005已经成为一个优秀的 新概念 SQL Server 2005 教程 18 数据平台。 1. Notification Services 增强 Notification Services是一种新平台,用于生成发送并接收通知的高伸缩性应用程序。 Notification Services可以把及时的、个性化的消息发送给使用各种各样设备的数以千计乃至 以百万计的订阅方。 提 示 Notification Services 2.0是SQL Server 2000的一个可下载组件,发布于2002年。在SQL Server 2005中,Notification Services是集成在SQL Server里的。 SQL Server 2005 Notification Services包括如下几种新的功能: y 集成到SQL Server Management Studio中。 y SQL Server Notification Services支持将现有数据库用于实例和应用程序数据。 y SQL Server Notification Services增加了新的管理API。 y 可将Notification Services引擎驻留在自定义应用程序或进程中。 y Notification Services新增了标准事件提供程序。 y Notification Services添加或修改部分视图,简化了应用程序开发和故障排除。 2. Reporting Services 增强 SQL Server 2005 Reporting Services(SSRS)是基于服务器的报表技术,它支持报表的 创作、分发、管理和最终用户访问。Reporting Services最初是作为SQL Server 2000的组件引 入的。 SQL Server 2005 Reporting Services增强了报表的功能,包括新的打印功能、最终用户 排序、多值参数以及通过Microsoft SharePoint Web部件进行的报表导航和查看。对报表创 作进行了扩展,以支持业务报表用户或分析人员即时生成报表。同时,也增强了Reporting Services可编程性和可管理性。 3. 新增的 Service Broker Microsoft SQL Server 2005引入了Service Broker,这是一项全新的技术,可用于生成数 据库加强型的安全、可靠以及可扩展的分布式应用程序。 Service Broker是数据库引擎的一部分。Service Broker为单个SQL Server实例中的应用 程序和将工作分布在多个SQL Server实例上的应用程序提供独特的功能。 在SQL Server实例中,Service Broker提供了一个功能强大的异步编程模型。异步编程 允许数据库应用程序在资源可用时执行占用大量资源的任务,以此来缩短响应时间,提高 吞吐量。Service Broker还会在SQL Server实例之间提供可靠的消息传递服务。 4. 数据库引擎增强 Microsoft SQL Server 2005在数据库引擎中引入了多项改进和新功能。增强了数据库引 擎的可编程性、可管理性和可伸缩性。 19 第2章 Chapter 02 初识SQL Server 2005 5. 数据访问接口方面的增强 Microsoft SQL Server 2005在用于访问SQL Server数据库中数据的编程接口方面进行了 改进。SQL Server Database Engine的API包括SqlClient托管命名空间、SQL本机客户端和 SQLXML。SQL Server 2005在这些API中进行的改进提高了程序员的生产效率,并支持访 问SQL Server数据库的应用程序中的新增功能。这些功能包括: y ODBC和OLE DB程序具有更多功能。 y .NET Framework公共语言运行时集成。 y Web访问。 6. Analysis Services 的增强功能(SSAS) Microsoft SQL Server 2005 Analysis Services(SSAS)为商业智能提供额外的支持,在 使商业智能解决方案更易于创建、部署和管理的同时,为其提供增强的可伸缩性、可用性 和安全性。Analysis Services中添加了很多新增功能以及对现有功能的改进。这些功能增强 体现在下面几个方面: y 用户体验方面的增强。 y 服务器增强。 y 多维数据集的增强。 y 维度方面的增强。 y 数据挖掘方面的增强。 y 开发方面的增强。 y 管理增强。 7. Integration Services 的增强 Microsoft SQL Server 2005 Integration Services(SSIS)是用于构建高性能数据集成解决 方案的新的、高度可伸缩的平台,这些解决方案的用途包括提取、转换和加载(ETL)包 以建立数据仓库。Integration Services代替了Data Transformation Services(DTS),DTS最 初是作为SQL Server 7.0的组件引入的。 在SQL Server 2005中,Microsoft设计并构建了全新的ETL产品——SQL Server 2005 Integration Services(SSIS)。Integration Services解决了很多DTS中遇到的困难和限制。SSIS 的增强功能包括新的可扩展的体系结构、新的包设计器以及很多新任务、循环结构和转换, 同时还在包部署、管理和性能方面进行了改进。 8. 复制增强 Microsoft SQL Server 2005对于复制引入了大量新功能和改进。主要包括如下几个方 面。 y 复制安全性增强功能。 y 复制可管理性增强功能。 y 复制可用性增强功能。 新概念 SQL Server 2005 教程 20 y 异类复制增强功能。 y 复制可编程性功能增强。 y 复制移动性增强功能。 y 复制的可伸缩性和性能增强。 y 可更新事务性订阅的增强功能。 9. 工具和实用工具增强 SQL Server 2005在用户界面和实用工具方面作了如下增强和改进。 y 新增的Business Intelligence Development Studio,用于开发和管理商业智能对象。 y 新SQL Server Management Studio,用于开发和管理SQL Server数据库和复制拓扑。 y 新SQL Server配置管理器,管理各种SQL Server组件的操作系统服务。 y 新数据库引擎优化顾问,用于优化SQL Server数据库性能。 y 新增的Analysis Services设计器和向导,用于部署和迁移Analysis Services。 y SQL Server Profiler得到了增强。 y SQL Server导入和导出向导的增强。 y 新增的Integration Services设计器和向导,为Business Intelligence Development Studio中的SSIS用户界面进行了重新设计 另外,SQL Server 2005对命令提示行实用工具也进行了很大的改进。 2.2 SQL Server 2005版本及系统需求 在安装SQL Server 2005以前,应该了解SQL Server 2005的各个版本功能及其需要的软 硬件配置,并保证它们正常运转。应该在安装之前,检查硬件和软件的安装情况,这可以 避免很多安装过程中发生的问题。 2.2.1 SQL Server 2005的版本 据应用程序的需要,安装要求可能有很大不同。SQL Server 2005的不同版本能够满足 企业和个人独特的性能、运行时以及价格要求。需要安装哪些SQL Server 2005组件也要根 据企业或个人的需求而定。 SQL Server 2005包括如下5个版本: y SQL Server 2005 Enterprise Edition(企业版,32位和64位) Enterprise Edition是最 全面的SQL Server版本,是超大型企业的理想选择,能够满足最复杂的要求。该版 本达到了支持超大型企业进行联机事务处理(OLTP)、高度复杂的数据分析、数 据仓库系统和网站所需的性能水平。其全面的商业智能和分析能力及其高可用性 功能(例如故障转移群集),使它可以处理大多数关键业务的企业工作负荷。该 版本还推出了一种适用于32位或64位平台的120天Evaluation Edition(评估版本)。 y SQL Server 2005 Standard Edition(标准版,32位和64位) Standard Edition是适合 21 第2章 Chapter 02 初识SQL Server 2005 中小型企业的数据管理和分析平台。它包括电子商务、数据仓库和业务流解决方 案所需的基本功能。其集成商业智能和高可用性功能可以为企业提供支持其运营 所需的基本功能。Standard Edition是需要全面的数据管理和分析平台的中小型企业 的理想选择。 y SQL Server 2005 Workgroup Edition(工作组版,仅适用于32位) 对于那些需要 在大小和用户数量上没有限制的数据库的小型企业,Workgroup Edition是理想的数 据管理解决方案。Workgroup Edition可以用作前端 Web服务器,也可以用于部门 或分支机构的运营。它包括SQL Server产品系列的核心数据库功能,并且可以轻松 地升级至Standard Edition或Enterprise Edition。Workgroup Edition是理想的入门级数 据库,具有可靠、功能强大且易于管理的特点。 y SQL Server 2005 Developer Edition(开发版,32位和64位) Developer Edition使 开发人员可以在 SQL Server 上生成任何类型的应用程序。它包括SQL Server 2005 Enterprise Edition的所有功能,但有许可限制,只能用于开发和测试系统,而不能 用作生产服务器。Developer Edition是独立软件供应商(ISV)、咨询人员、系统 集成商、解决方案供应商以及创建和测试应用程序的企业开发人员的理想选择。 Developer Edition可以根据生产需要升级至SQL Server 2005 Enterprise Edition。 y SQL Server 2005 Express Edition(精简版,仅适用于32位) SQL Server Express 是一个免费、易用且便于管理的数据库。SQL Server Express与Microsoft Visual Studio 2005集成在一起,可以轻松开发,其特点为功能丰富、存储安全及可快速部 署的数据驱动应用程序。SQL Server Express是免费的,可以再分发(受制于协议), 还可以起到客户端数据库以及基本服务器数据库的作用。SQL Server Express是低 端ISV、低端服务器用户、创建Web应用程序的非专业开发人员以及创建客户端应 用程序的编程爱好者的理想选择。 2.2.2 SQL Server 2005的硬件需求 SQL Server 2005的硬件需求如表2.1所示。 关于内存的大小,会由于操作系统的不同,而可能需要额外的内存。实际的硬盘空间 要求也会因系统配置和选择安装的应用程序和功能的不同而异。 注 意 如果不满足处理器类型的要求,系统配置检查器(SCC)将阻止安装程序运行。如 果不满足最低或建议的处理器速度要求,SCC将向用户发出警告但不会阻止安装程序运 行。多处理器计算机上将不会出现警告。如果不满足最低或建议的RAM要求,SCC将向 用户发出警告但不会阻止安装程序运行。内存要求仅针对此版本,它不反映操作系统的其 他内存要求。SCC将在安装开始时确认内存是否可用。 表2.1 SQL Server 2005的硬件需求 项目 最低需求 计算机 需要Pentium III 600 MHz兼容处理器或更高速度的处理器,建议1 GHz或更 新概念 SQL Server 2005 教程 22 高 内存(RAM) 企业版、标准版、开发版和工作站版:至少512 MB,建议1 GB或更大 Express Edition:至少192 MB,建议512 MB或更大 硬盘空间 数据库引擎和数据文件、复制以及全文搜索:150 MB Analysis Services和数据文件:35 KB Reporting Services和报表管理器:40 MB Notification Services引擎组件、客户端组件和规则组件:5 MB Integration Services:9 MB 客户端组件:12 MB 管理工具:70 MB 开发工具:20 MB SQL Server 联机丛书和 SQL Server Mobile联机丛书:15 MB 示例和示例数据库:390 MB 监视器 SQL Server图形工具需要VGA或更高分辨率,分辨率至少为1024×768像素 定位设备 Microsoft鼠标或兼容设备 CD-ROM驱动器 通过CD或DVD媒体进行安装时需要相应的CD或DVD驱动器 2.2.3 SQL Server 2005的软件需求 SQL Server 2005包括企业版、标准版、开发版和个人版,每个版本对操作系统的要求 都有所不同,每个版本及其组件安装所需要的操作系统如表2.2所示。 除了操作系统要求外,SQL Server 2005安装程序需要Microsoft Windows Installer 3.1或 更高版本以及Microsoft数据访问组件(MDAC)2.8 SP1或更高版本。可以从 Microsoft网站 下载MDAC 2.8 SP1。 SQL Server安装程序还需要安装以下的软件组件: y Microsoft Windows .NET Framework 2.0。 y Microsoft SQL Server本机客户端。 y Microsoft SQL Server安装程序支持文件。 注 意 SQL Server 2005的某些功能要求必须在Microsoft Windows 2000/2003 Server(任何版 本)下才可以使用。另外,在32位平台上运行SQL Server 2005的要求与在64位平台上的要 求不同。在具体使用时可以查阅SQL Server 2005的帮助文档。另外,SQL Server 2005 Express Edition不安装.NET Framework 2.0。在安装SQL Server 2005 Express Edition之前, 必须安装.NET Framework 2.0。可以从Microsoft网站下载.NET Framework 2.0。 表2.2 SQL Server 2005各种版本及组件安装所需要的操作系统 SQL Server版本 操作系统要求 23 第2章 Chapter 02 初识SQL Server 2005 Enterprise Edition (企业版) Windows 2000 Server SP4/Advanced Server SP4/Datacenter Edition SP4 Windows 2003 Server SP1/Enterprise Edition SP1/Datacenter Edition SP1 Windows Small Business Server 2003 Standard Edition SP1/ Premium Edition SP1 Standard Edition (标准版) Windows 2000 Professional Edition SP4/Server SP4/Advanced Server SP4/Datacenter Edition SP4 Windows XP Professional Edition SP2/Media Edition SP2/Tablet Edition SP2 Windows 2003 Server SP1/Enterprise Edition SP1/Datacenter Edition SP1 Windows Small Business Server 2003 Standard Edition SP1/Premium Edition SP1 Workgroup Edition (工作组版) Windows 2000 Professional Edition SP4/Server SP4/Advanced Server SP4/Datacenter Edition SP4 Windows XP Professional Edition SP2/Media Edition SP2/Tablet Edition SP2 Windows 2003 Server SP1/Enterprise Edition SP1/Datacenter Edition SP1 Windows Small Business Server 2003 Standard Edition SP1/Premium Edition SP1 Developer Edition (开发版) Windows 2000 Professional Edition SP4/Server SP4/Advanced Server SP4/Datacenter Edition SP4 Windows XP Home Edition SP2/Professional Edition SP2/Media Edition SP2/Tablet Edition SP2 Windows 2003 Server SP1/Enterprise Edition SP1/Datacenter Edition SP1 Windows Small Business Server 2003 Standard Edition SP1/Premium Edition SP1 Express Edition (精简版) Windows 2000 Professional Edition SP4/Server SP4/Advanced Server SP4/Datacenter Edition SP4 Windows XP Home Edition SP2/Professional Edition SP2/Media Edition SP2/Tablet Edition SP2 Windows 2003 Server SP1/Enterprise Edition SP1/Datacenter Edition SP1/Web Edition SP1 Windows Small Business Server 2003 Standard Edition SP1 Windows Small Business Server 2003 Premium Edition SP1 Evaluation Edition (评估版) Windows 2000 Professional Edition SP4/Server SP4/Advanced Server SP4/Datacenter Edition SP4/ Windows XP Professional Edition SP2/Media Edition SP2/Tablet Edition SP2 Windows 2003 Server SP1/Enterprise Edition SP1/Datacenter Edition SP1 Windows Small Business Server 2003 Standard Edition SP1/Premium Edition SP1 2.2.4 网络软件 客户端要通过网络连接与SQL Server正确进行通信,就必须选用一种共同的进程间通 信(Inter-Process Communication,IPC)机制,以便在客户端和SQL Server之间来回传递网 络数据包。SQL Server支持几种不同的IPC机制,这些IPC机制是通过动态链接库(DLL) 形式的网络库来实现的。如果客户端和SQL Server并没有使用相同的网络链接库,那么它 们之间就无法进行通信。服务器可以同时监听多个网络链接库。 新概念 SQL Server 2005 教程 24 注 意 服务器可以一次监听或监视多个网络库。在安装过程中,SQL Server 2005安装程序将所 有网络库安装到计算机上,并允许配置部分或全部网络库。如果没有配置某个网络库,则服 务器将无法监听该网络库。安装完成后,可以使用SQL Server配置管理器更改这些配置。 网络库用于在客户端和运行SQL Server的服务器之间传递网络数据包。在决定添加网 络库之前,应该阅读SQL Server在线参考书中有关每一个可用的网络链接库的内容,这样 就能知道是否需要这种网络链接库。装载不需要的网络链接库会占用分配给SQL Server的 珍贵内存资源。 若要连接到SQL Server Database Engine,必须启用网络协议。Microsoft SQL Server 可 一次通过多种协议为请求服务。客户端用单个协议连接到 SQL Server。如果客户端程序不 知道 SQL Server 在侦听哪个协议,可以配置客户端按顺序尝试多个协议。 1. Shared Memory 网络库 Shared Memory是可供使用的最简单协议,没有可配置的设置。由于使用Shared Memory 协议的客户端仅可以连接到同一台计算机上运行的SQL Server实例,因此它对于大多数数 据库活动而言是没用的。如果怀疑其他协议配置有误,可以使用Shared Memory协议进行故 障排除。 2. Named Pipes(命名管道)网络库 Named Pipes是为局域网而开发的协议。内存的一部分被某个进程用来向另一个进程传 递信息,因此一个进程的输出就是另一个进程的输入。第二个进程可以是本地的(与第一 个进程位于同一台计算机上),也可以是远程的(位于联网的计算机上)。 传统上,Windows NT/2000服务器都使用Named Pipes来相互通信,SQL Server也不例 外。当使用Named Pipes时,SQL Server为与客户端通信而侦听“\\sql_server_name\ pipe\sql\query”,这是一个隐含的共享目录。在这里“sql_server_name”表示安装SQL Server 的计算机名字。 所有微软的客户端操作系统都具有通过Named Pipes与SQL Server进行通信的能力。 Named Pipes可以被删除,但是只能在安装之后这样做。因为在安装过程中需要Named Pipes, 如果在安装时删除了Named Pipes,安装过程就会失败。 3. TCP/IP Sockets 网络库 TCP/IP是Internet上广泛使用的通用协议。它与互联网络中硬件结构和操作系统各异的 计算机进行通信。它包括路由网络流量的标准,并能够提供高级安全功能。它是目前在商 业中最常用的协议。 如果使用的网络是百分之百基于TCP/IP的,并且其中的一些基于UNIX的客户端要访问 SQL Server,那么就应该考虑使用TCP/IP Sockets网络链接库。这种网络链接库使用标准的 TCP/IP Sockets应用程序编程接口作为进程间通信机制。 25 第2章 Chapter 02 初识SQL Server 2005 4. 虚拟接口适配器(Virtual Interface Adapter,VIA) VIA协议和VIA硬件一同使用。 注 意 SQL Server 2005不支持Banyan VINES顺序包协议(SPP)、多协议、AppleTalk和 NWLink IPX/SPX网络协议。以前使用这些协议连接的客户端必须选择其他协议才能连接 到SQL Server 2005。 2.2.5 Internet要求 SQL Server 2005的安装还对Internet提出了要求,如表2.3所示。 表2.3 SQL Server 2005的Internet要求 组件 要求 Internet 软件 所有 SQL Server 2005 的安装都需要 Microsoft Internet Explorer 6.0 SP1 或 更高版本,因为 Microsoft 管理控制台(MMC)和 HTML 帮助需要它。 只需 Internet Explorer 的最小安装即可满足要求,且不要求 Internet Explorer 是默认浏览器 如果只安装客户端组件且不需要连接到要求加密的服务器,则 Internet Explorer4.01(带 Service Pack 2)即可满足要求 Internet 信息服务(IIS) 安装 Microsoft SQL Server 2005 Reporting Services(SSRS)需 要 IIS 5.0 或 更高版本 ASP.NET 2.02 Reporting Services 需要 ASP.NET 2.0。安 装 Reporting Services 时,如果尚 未启用 ASP.NET,则 SQL Server 安装程序将启用 ASP.NET 注 意 在故障转移群集上不支持Shared memory。另外,64位版本的SQL Server 2005的网络 软件和Internet要求与32位版本的要求相同。如果在64位服务器上安装Reporting Services (64位),则必须安装64位版本的ASP.NET。如果在64位服务器的32位子系统(WOW64) 上安装Reporting Services(32位),则必须安装32位版本的ASP.NET。Reporting Services 不支持同时在64位平台上和64位服务器的32位子系统(WOW64)上进行并行配置。 2.3 SQL Server 2005的安装 在使用SQL Server 2005以前,首先要进行安装。本节介绍安装过程中所涉及到的选项 的基础知识,以及具体的安装过程。最后对其他几种安装方式进行了介绍。 2.3.1 SQL Server的配置选项 在安装SQL Server之前,应该了解SQL Server所涉及到的安装选项。SQL Server安装有 很多选项,在安装时应仔细考虑每一选项的含义。因此,在安装SQL Server以前,先讨论 新概念 SQL Server 2005 教程 26 一下这些选项。 1. 排序规则 排序规则指定表示数据集中每个字符的位模式。排序规则还决定用于数据排序和比较 的规则。SQL Server 2005支持在单个数据库中存储具有不同排序规则的对象,即SQL Server 数据库中每列都可以有各自的排序规则。对于非Unicode列,排序规则设置指定数据的代码 页,从而指定可以表示哪些字符。数据可以在Unicode列之间无缝地移动。在非Unicode列 之间移动数据时,数据不能无缝地移动,而必须经当前代码页转换。 如果Transact-SQL语句运行于各自都具有不同排序规则设置的数据库的上下文中,则 其运行结果可能会不同。如果可能,最佳实践应包括对组织使用标准化排序规则。如果已 在组织中的所有系统上使用标准的排序规则设置,则无需在每个字符或Unicode表达式中显 式地指定排序规则。如果必须使用具有不同排序规则和代码页设置的对象,则必须对查询 进行编码以考虑排序规则优先级的规则。 排序规则的特征是区分语言、区分大小写、区分重音、区分假名以及区分全半角。SQL Server 2005排序规则包括下列分组: y Windows排序规则 Windows排序规则根据关联的Windows区域设置来定义字符 数据的存储规则。在Windows排序规则中,使用与Unicode数据相同的算法实现非 Unicode数据的比较。Windows基本排序规则指定应用字典排序时所用的字母表或 语言,以及用于存储非Unicode字符型数据的代码页。Unicode排序和非Unicode排 序都与特定Windows版本中的字符串比较相兼容。这可以保持SQL Server中不同数 据类型间的一致性,也使开发人员能够使用与SQL Server所使用的相同的规则(即 通过调用Microsoft Win 32 API的CompareStringW函数)在应用程序中对字符串进 行排序。 y 二进制排序规则 二进制排序规则基于区域设置和数据类型所定义的编码值的顺 序,对数据进行排序。SQL Server中的二进制排序规则强制使用二进制排序顺序, 定义了要使用的语言区域设置和ANSI代码页。由于二进制排序规则相对简单,因 此对改进应用程序的性能非常有用。对于非Unicode数据类型,数据比较将基于 ANSI代码页中定义的码位。对于Unicode数据类型,数据比较将基于Unicode码位。 对于Unicode数据类型的二进制排序规则,数据排序将不考虑区域设置。例如,对 Unicode数据应用Latin_1_General_BIN和 Japanese_BIN,会得到完全相同的排序结 果。 y SQL Server 排序规则 SQL Server排序规则提供与SQL Server早期版本兼容的排 序顺序。SQL Server排序规则基于由SQL Server为非Unicode数据(例如char和 varchar数据类型)定义的早期SQL Server排序顺序。非Unicode数据的字典排序规 则与Windows操作系统提供的任何排序例程都不兼容,但Unicode数据的排序与特 定版本的Windows排序规则兼容。由于SQL Server排序规则对非Unicode数据和 Unicode数据使用不同的比较规则,因此对于相同数据的比较可能看到不同的结果 (取决于基本数据类型)。 27 第2章 Chapter 02 初识SQL Server 2005 2. SQL Server 2005 的命名实例和多实例 使用Microsoft SQL Server 2005,可以选择在一台计算机上安装 SQL Server的多个副本 或多个实例。当设置新的SQL Server 2005安装或维护现有安装时,可以将其指定为: y SQL Server的默认实例 此实例由运行它的计算机的网络名称标识。使用以前版本 SQL Server客户端软件的应用程序可以连接到默认实例。SQL Server 7.0版或SQL Server 2000版服务器可作为默认实例操作。但是,一台计算机上每次只能有一个版 本作为默认实例运行。 y SQL Server的命名实例 该实例通过计算机的网络名称加上实例名称以<计算机名 称>\<实例名称>格式进行标识。应用程序必须使用SQL Server 2005客户端组件连 接到命名实例。计算机可以同时运行任意数目的SQL Server命名实例。 提 示 新实例名称必须以字母、“和”符号(&)或下划线(_)开头,可以包含数字、字母 或其他字符。SQL Server系统名称和保留名称不能用作实例名称。例如,default一词不能 用作实例名称,因为它是安装程序使用的保留名称。 在使用SQL Server 2005精简版、SQL Server 2005标准版或SQL Server 2005企业版时, 单个和多个SQL Server 2005实例(默认或命名)都是可用的。 (1)默认实例 在同时运行以前版本的SQL Server的计算机上,无法安装SQL Server 2005的默认实例。 必须将以前版本的SQL Server安装升级到SQL Server 2005默认实例,或者保留以前版本SQL Server的默认实例并安装SQL Server 2005的命名实例。 (2)多实例 当一台计算机安装有多个SQL Server 2005实例时,就会出现多实例。每个实例的操作 都与同一台计算机上的其他任何实例分开,而应用程序可以连接任何实例。在单台计算机 上可以运行的实例数目取决于可用资源。 在未安装过SQL Server的计算机上安装SQL Server 2005时,安装程序指定安装默认实 例。但是,通过“命名实例”选项,并输入实例名,也可以将SQL Server 2005安装为命名 实例。 每个命名实例都由非重复的一组服务组成,并且对于排序规则和其他选项可以有完全 不同的设置。目录结构、注册表结构和服务名称都反映了所指定的具体实例名称。 3. 服务账户 根据选择要安装的Microsoft SQL Server组件,SQL Server 2005安装程序可安装以下10 种服务: y SQL Server Database Services。 y SQL Server Agent(SQL Server代理)。 y Analysis Services。 新概念 SQL Server 2005 教程 28 y Reporting Services。 y Notification Services。 y Integration Services。 y Full Text Search(全文搜索)。 y SQL Server Browser(浏览器)。 y SQL Server Active Directory Helper。 y SQL 编写器。 其中SQL Server服务是SQL Server的引擎,直接通过Transact-SQL管理数据库。 和大多数Windows服务一样,SQL Server的10个服务可以在服务器启动时自动启动。作 为初始化过程的一部分,每个服务都必须登录到服务器上,这和用户登录到Windows上去 访问网络资源很相似。 一个Windows服务可以通过两种方式登录到服务器上: y 使用Windows内置的本地系统(Local System)账户来登录 本地系统账户是 Windows系统专用的特殊账户。当服务使用本地系统账户登录时,这个服务就在该 物理服务器的安全上下文中运行。也就是说,该服务有权限在本地服务器上进行 操作,但是不能和网络中的其他部分交互。对于大多数服务,这种限制并不会带 来任何问题。 y 使用特殊账户来登录 这里特殊的账户是指专门为服务而创建的账户,通过使用 该账户,服务可以在这个账户所属的安全上下文中运行,该账户通常是组织中的 账户域。 注 意 SQL Server和SQL Server Agent服务可以通过本地系统账户来登录,但是这样会限制 它们和其他SQL Server进行通信的能力。这种设置对于小型的或单个服务器是可以的,但 是当安装了多个SQL Server并且需要进行交互时,SQL Server Agent服务就不应该使用本 地系统账户了,而应该使用域账户。 Windows的服务账户应该(但不是必须)在安装SQL Server之前创建。在安装的过程中, 会提示输入该服务账户。如果在安装之前忘记了创建服务账户,可以使用本地系统账户来 代替,在安装完成后,可以在Windows的控制面板的服务应用中修改该服务的启动值。 在为SQL Server和SQL Server Agent服务创建登录账户时,应注意下面的问题: y 该账户应该属于账户域的Windows服务器管理员全局组。 y 不要选择“在下次登录时修改密码”(Change Password at Next Logon)复选框。 y 必须选择“密码永不过期”(Password Never Expires)复选框。 y 应指定一个口令,防止其他用户使用该账户登录Windows,因为该账户不应该用来 登录Windows,而只应该被SQL Server Agent服务来使用。 y 必须赋予该账户“作为服务登录”(Log On as a Services)权限,但是对于Windows 操作系统,则没有该选项。“作为服务登录”权限是在指定其作为服务账户时自 29 第2章 Chapter 02 初识SQL Server 2005 动赋予的。 4. 验证模式 验证模式指的是安全方面的问题,每一个用户要使用SQL Server,都必须经过验证。 在安装过程中,系统会提示选择验证模式。有两种验证模式: y Windows身份验证模式 在该验证模式下,SQL Server检测当前使用的Windows用 户账户,并在Syslogins表中查找该账户,以确定该账户是否有权限登录。在这种 方式下,用户不必提供密码或者登录名让SQL Server验证。这是默认的身份验证模 式,比混合模式安全得多。Windows身份验证使用Kerberos安全协议,通过强密码 的复杂性验证提供密码策略强制,提供账户锁定支持,并且支持密码过期。 y 混合验证模式(Windows身份验证和SQL Server身份验证) 该模式允许以SQL Server验证方式或者Windows验证方式来进行连接。具体使用哪个方式,则取决于 在最初的通信中使用的网络库。如果一个用户使用TCP/IP Sockets进行登录验证, 它将使用SQL Server验证模式。如果使用命名管道,登录验证将使用Windows验证 模式。这种登录模式可以更好地适应用户的各种环境。 2.3.2 从光盘直接安装 在了解了前面的选项后,就可以安装SQL Server 2005了。整个安装过程都是在安装向 导提示下完成的。具体安装步骤如下。 将SQL Server 2005的安装光盘放入光驱中,运行光驱中的autorun.exe程序,出现安 装启动画面,如图2.1所示。 图 2.1 安装启动画面 提 示 如果光驱设置了自动运行选项,则放入SQL Server 2005的安装光盘后,将自动运行 新概念 SQL Server 2005 教程 30 autorun.exe程序。 在“最终用户许可协议”对话框中,选择“我接收许可条款和条件”复选框,如 图2.2所示。然后单击“下一步”按钮。 图 2.2 “最终用户许可协议”对话框 此时,在弹出的“安装必备组件”对话框中列出了安装SQL Server 2005之前必须 要安装的软件。单击“安装”按钮,开始安装和配置这些组件,如图2.3所示。根据用户计 算机中软件的安装情况不同,安装必备组件的内容也会有所不同。 图 2.3 “安装必备组件”对话框 安装完成后,单击“下一步”按钮,打开“安装向导”对话框,如图2.4所示。 正在安装的 组件名称 31 第2章 Chapter 02 初识SQL Server 2005 图 2.4 “安装向导”对话框 单击“下一步”按钮,打开“系统配置检查”对话框。对系统配置进行检查后, 然后显示相关的信息,如图2.5所示。 图 2.5 “系统配置检查”对话框 单击“下一步”按钮,弹出“注册信息”对话框,输入姓名、公司名称和注册码 后,单击“下一步”按钮。 此时,会打开“要安装的组件”对话框,如图2.6所示。在此对话框中,可以选择 要安装的组件。如果要安装单个组件,或者设置安装路径等,则可以单击“高级”按钮进 行选择。 单击“下一步”按钮,打开“实例名”对话框,如图2.7所示。在此对话框中,可 以添加和维护SQL Server 2005实例。如果选择“默认实例”单选项,则将安装SQL Server 2005 的默认实例,默认实例名为MSSQLSERVER。若要安装命名实例,可取消“默认实例”单 选框的选择,然后在下面的文本框中输入实例名。 新概念 SQL Server 2005 教程 32 图 2.6 “要安装的组件”对话框 图 2.7 “实例名”对话框 选择“默认实例”单选项,单击“下一步”按钮,打开“服务账户”对话框,如 图2.8所示。在此对话框中,可以为SQL Server、SQL Browser、Analysis Services和“SQL Server Agent(SQL Server代理)”服务选择登录账户。 SQL Server和SQL Server Agent在所有支持的操作系统上都作为Microsoft Windows服 务来运行。由于SQL Server和SQL Server Agent在Windows中作为服务来运行,因此必须给 SQL Server和SQL Server Agent指派Windows用户账户。通常,给SQL Server和SQL Server Agent指派相同的用户账户,可以是本地用户账户,或者域用户账户。但是,也可以在安装 过程中为每个服务自定义设置,这通过选择“为每个服务账户进行自定义”复选框来完成。 单击可以选择 单个组件或者 选择安装路径 33 第2章 Chapter 02 初识SQL Server 2005 图 2.8 “服务账户”对话框 配置完成后,单击“下一步”按钮,打开“身份验证模式”对话框,如图2.9所示。 若选择“混合模式(Windows身份验证和SQL Server身份验证)”单选项,则还需要输入sa (超级用户)的登录密码。 图 2.9 “身份验证模式”对话框 单击“下一步”按钮,打开“排序规则设置”对话框,如图2.10所示。可根据自 己的需要进行设置,也可以保持默认设置。该对话框中的各选项含义如下: y “为每个服务账户进行自定义”复选框 可以为数据库引擎和Analysis Services指 定不同的排序规则设置,也可以为所有的服务指定单一的排序规则。选中“为每 个服务账户进行自定义”复选框,可以从下拉列表中的服务列表选择服务,然后 为该服务选择排序规则和排序顺序。 y “排序规则指示符和排序顺序”选项 指定SQL Server 2005的此实例所使用的排 序规则。为英语系统区域设置默认选定SQL排序规则。非英语区域设置的默认排 序规则是Windows系统区域设置(“非 Unicode 程序语言”设置)或控制面板的 “区域和语言选项”中最接近的等效设置。仅当SQL Server的此安装的排序规则设 选择在安装结束后 自动启动的服务 新概念 SQL Server 2005 教程 34 置必须与SQL Server的另一实例所使用的排序规则设置相匹配,或者必须与另一台 计算机的 Windows 系统区域设置相匹配时,才应更改默认设置。 图 2.10 “排序规则设置”对话框 y “SQL排序规则”选项 匹配与 SQL Server 7.0、8.0或更早版本相兼容的设置。 “SQL 排序规则”选项提供与 SQL Server 的早期版本的兼容性。 注 意 SQL排序规则不能用于Analysis Services。如果选择了要在安装数据库引擎时使用的 SQL排序规则,则SQL Server安装程序将基于所选的SQL排序规则为Analysis Services选择 最匹配的Windows排序规则。如果数据库引擎和Analysis Services的排序规则不匹配,可能 得到不一致的结果。为了确保数据库引擎与 Analysis Services之间结果的一致性,最好使 用Windows排序规则。 单击“下一步”按钮,打开“错误和使用情况报告设置”对话框,如图2.11所示。 在此对话框中,可以选择自动将SQL Server 2005的错误报告和功能使用情况发送到 Microsoft公司或者指定的服务器。 图 2.11 “错误和使用情况报告设置”对话框 35 第2章 Chapter 02 初识SQL Server 2005 单击“下一步”按钮,打开“准备安装”对话框,如图2.12所示。在该对话框中 显示了要安装的SQL Server 2005组件,如果还需要安装其他组件,则可以单击“上一步” 按钮,返回到前面几步重新进行选择。 图 2.12 “准备安装”对话框 单击“安装”按钮,开始安装SQL Server 2005的选定组件,并打开“安装进度” 对话框,显示安装内容及进度,如图2.13所示。根据计算机的配置不同,安装所花费的时 间也不同。 安装完成后,单击“下一步”按钮,打开“完成Microsoft SQL Server 2005安装” 对话框,如图2.14所示。在此对话框中,显示了摘要日志等信息。单击“完成”按钮,此 时会提示重新启动计算机,选择“是”,重新启动计算机后,完成安装。 图 2.13 “安装进度”对话框 图 2.14 “完成Microsoft SQL Server 2005安装”对话框 2.3.3 其他安装方式 除了上面介绍的从光盘安装SQL Server 2005外,还可以进行网络共享安装和无人值守 安装。 将要安装的SQL Server 2005组件 新概念 SQL Server 2005 教程 36 注 意 以前版本的SQL Server安装时,选择的选项都被记录进安装程序初始化文件 (Setup.iss)中。Setup.iss存放在系统根目录(%windir%)下。SQL Server 2005不支持远 程安装,也不支持记录无人参与的(.iss)安装。 1. 从网络共享中安装 如果需要在多台计算机上安装SQL Server 2005,特别是只有一张SQL Server 2005的安 装光盘时,则可以将SQL Server 2005的安装文件复制到网络中共享的文件夹中,然后在各 台计算机上,从共享的文件夹中安装SQL Server 2005。 如果从远程共享安装SQL Server 2005,必须使用对该远程共享具有读取权限和执行权 限的域账户。 2. 从命令提示符安装 SQL Server 2005安装程序除提供图形用户界面外,还提供一个命令提示符界面。使用 命令提示语法可以自定义安装程序安装SQL Server 2005的方式。 例如,要从命令提示符安装SQL Server 2005的独立新实例,其操作步骤如下: 将SQL Server 2005安装光盘或者DVD插入光盘驱动器。 要安装识别实例的组件(数据库引擎、SQL Server Agent、Analysis Services和 Reporting Services),在命令提示符下,输入下述命令: Start /wait \setup.exe /qb INSTANCENAME= ADDLOCAL = SQL_Engine, SQL_Replication SAPWD= 其中,指定SQL Server 2005安装DVD的驱动器符号;/qb选项用于显示所 有安装程序对话框和错误消息;用于指定实例名称;ADDLOCAL关键字指 定要安装的组件,如果要安装所有组件,则在命令行上指定“ADDLOCAL=All”; 指定强sa密码。 setup.exe程序还可以使用其他关键字进行设置。例如,INSTALLSQLDIR关键字用于指 定安装目录等。关于这些关键字的使用,可以查看SQL Server 2005的有关文档。 使用这些关键字除了可以安装SQL Server 2005的组件外,还可以更新或删除SQL Server 2005组件。 3. 无人值守安装 可以通过.ini 文件来进行无人值守安装。在执行无人值守安装以前,必须创建一个用 于安装的.ini文件,该文件记录了安装过程中需要的所有信息。然后利用该文件,在命令提 示符启动无人值守安装。 无人值守安装的操作步骤如下: 创建用于无人值守安装的.ini文件。利用安装DVD中的Servers目录下的模板文件 template.ini文件来创建。 在命令提示符下,执行下述命令: 37 第2章 Chapter 02 初识SQL Server 2005 Setup.exe /settings C:/set.ini /qn 其中,Setup.exe命令后面是/settings选项,该选项指定包含安装参数设置的.ini文件名; /qn选项用于取消安装程序用户界面。 提 示 Setup.exe文件位于SQL Server 2005安装DVD的Servers目录下。另外,如果指定 /qn 选项,则所有安装程序消息(包括错误消息)都将写入安装程序日志文件。 2.3.4 从其他版本升级到SQL Server 2005 可以将SQL Server 2000 Service Pack 3(SP3)或更高版本的实例以及SQL Server 7.0 SP4 或更高版本的实例直接升级到SQL Server 2005。通过安装程序可以完成大多数升级操作; 但是,某些组件支持或要求在运行安装程序后迁移应用程序或解决方案。 将以前版本的SQL Server升级到SQL Server 2005的操作步骤如下: 将SQL Server 2005的安装光盘或DVD插入光盘驱动器。如果该光盘不自动运行, 请双击该光盘根目录中的Splash.hta文件。 开始SQL Server 2005的安装过程,依照提示进行操作。 在“实例名”页上,请选择要升级的默认实例或命名实例。如果已经安装了默认 实例或命名实例,并且为安装的软件选择了现有实例,则安装程序将升级所选的实例并提 供安装其他组件的选项。 y 若要升级计算机上已安装的SQL Server默认实例,选择“默认实例”选项,然后单 击“下一步”按钮继续。 y 若要升级计算机上已安装的SQL Server命名实例,选择“命名实例”选项,然后在 提供的空白处输入实例名,也可以在“实例名”页上单击“已安装的实例”选项, 从“已安装的实例”列表中选择一个实例,然后单击“确定”按钮以填充实例名 字段。选择要升级的实例之后,单击“下一步”按钮继续。 依照提示进行操作,直到完成升级安装即可。 2.4 SQL Server 2005的工具和实用工具概述 Microsoft SQL Server 2005提供了设计、开发、部署和管理关系数据库、Analysis Services 多维数据集、数据转换包、复制拓扑、报表服务器和通知服务器所需的工具。使用这些工 具和程序,可以设置和管理SQL Server进行数据库管理和备份,并保证数据库的安全和一 致。 在安装完成后,在“开始”菜单上,将鼠标移到Microsoft SQL Server 2005,即可看到 Microsoft SQL Server 2005的安装组件,如图2.15所示。 新概念 SQL Server 2005 教程 38 图 2.15 Microsoft SQL Server 2005 的组件 下面对这些组件做一些简单介绍,以便读者对Microsoft SQL Server 2005的组件及其功 能有一个大体的了解。 2.4.1 SQL Server Management Studio SQL Server Management Studio(SQL Server管理平台)是一个集成的环境,用于访问、 配置和管理所有SQL Server组件。SQL Server Management Studio组合了大量图形工具和丰 富的脚本编辑器,使各种技术水平的开发人员和管理员都能访问SQL Server。 SQL Server Management Studio将以前版本的SQL Server中包括的企业管理器和查询分 析器的各种功能,组合到一个单一环境中。此外,SQL Server Management Studio还提供了 一种环境,用于管理Analysis Services、Integration Services、Reporting Services和XQuery。 SQL Server Management Studio为开发者提供了一个熟悉的体验,为数据库管理人员提供了 一个单一的实用工具,使其能够通过易用的图形工具和丰富的脚本完成 任务。 启动和使用SQL Server Management Studio的操作步骤如下: 在“开始”菜单中依次选择“程序”| Microsoft SQL Server 2005|SQL Server Management Studio,打开“连接到服务器”对话框, 如图2.16所示。如果本地机器已经安装了SQL Server服务器,则可以在 “身份验证”下拉列表框中选择“Windows 身份验证”;如果在安装时 设置了SQL Server身份验证,则需进行相应的选择。 图 2.16 “连接到服务器”对话框 单击“连接”按钮,打开Microsoft SQL Server Management Studio窗口,如图2.17 所示。该窗口为一个标准的Visual Studio界面。默认情况下,左侧窗口为对象资源管理器, 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第 2 章 \Managment Studio.avi。 39 第2章 Chapter 02 初识SQL Server 2005 以树状结构显示数据库服务器及其中的数据库对象。对象资源管理器是SQL Server Management Studio 的一个组件,可连接到数据库引擎实例、Analysis Services、Integration Services、Reporting Services和SQL Server Mobile。它提供了服务器中所有对象的视图,并 具有可用于管理这些对象的用户界面。对象资源管理器的功能根据服务器的类型稍有不同, 但一般都包括用于数据库的开发功能和用于所有服务器类型的管理功能。 图 2.17 Microsoft SQL Server Management Studio 窗口 在对象资源管理器中,单击“数据库”前面的加号,打开“数据库”项,即可看 到当前数据库服务器中包含的所有数据库,如图2.18所示。 图 2.18 查看数据库信息 提 示 在图2.18中,对象资源管理器窗口中,目前只能看到master、model、msdb和tempdb 数据库。它们是系统数据库。关于系统数据库的详细信息,可以参考第3章。 在Microsoft SQL Server Management Studio窗口中,还可以管理和执行Transact- 数据库版本信息 对象资源管理器 显示master数据 库的详细信息 系统数据库 新概念 SQL Server 2005 教程 40 SQL脚本,这实际上集成了SQL Server 2000中的查询分析器的功能。单击工具栏中的“新 建查询”按钮,打开脚本编辑器窗口。此时,系统将自动生成一个脚本名称,如图2.19所 示。 图 2.19 脚本编辑器窗口 在脚本编辑器窗口中单击,在顶部的可用数据库下拉列表框中选择当前脚本应用 的数据库,然后在编辑窗口中输入下面的SQL语句: SELECT * FROM spt_values 单击工具栏中的“执行”按钮,在右侧窗口下面即可显示出执行结果,如图2.20 所示。 图 2.20 执行 SQL 语句 提 示 SELECT语句是最常用的SQL语句,spt_values是master数据库中的一个表。SELECT * FROM spt_values执行的操作是从spt_values表中查询数据。关于SQL语句,读者可以参考 第5章。 SQL语句 要应用的 数据库 执行结果 41 第2章 Chapter 02 初识SQL Server 2005 除了上面介绍的查看数据库、执行SQL语句功能外,SQL Server Management Studio还 具有管理SQL Server Database Engine、Analysis Services、Reporting Services、Notification Services以及SQL Server Mobile中的对象,导入导出导出或导入SQL Server Management Studio服务器注册,保存或打印由SQL Server Profiler生成的XML显示计划或死锁文件等功 能。这将在后面章节中详细介绍。 2.4.2 Business Intelligence Development Studio Business Intelligence Development Studio(商业智能开发平台)是一个集成的环境,用 于开发商业智能构造。Business Intelligence Development Studio包含一些项目模板,这些模 板可以提供开发特定构造的上下文。 在Business Intelligence Development Studio中开发项目时,可以将其作为某个解决方案 的一部分进行开发,而该解决方案独立于具体的服务器。例如,可以在同一个解决方案中 包括Analysis Services项目、Integration Services项目和Reporting Services项目。在开发过程 中,可以将对象部署到测试服务器中进行测试,然后,可以将项目的输出结果部署到一个 或多个临时服务器或生产服务器。 使用Business Intelligence Development Studio创建一个项目的操 作步骤如下: 在“开始”菜单上,依次选择“程序”| Microsoft SQL Server 2005 | SQL Server Business Intelligence Development Studio选项,打开 Business Intelligence Development Studio窗口,如图2.21所示。 图 2.21 SQL Server Business Intelligence Development Studio 窗口 在菜单栏中选择“文件”|“新建”|“项目”选项,打开“新建项目”对话框,如 图2.22所示。在此对话框中,可以选择项目类型和项目模板,并可以设置项目名称、解决 方案的名称等。另外,除了可以创建“商业智能项目”外,还可以创建Visual C++、Visual C #等类型的项目,当然前提是需要安装这些开发工具。 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第2章\BIDS.avi。 新概念 SQL Server 2005 教程 42 图 2.22 “新建项目”对话框 设置完成后,单击“确定”按钮,即可创建项目。 2.4.3 Analysis Services Microsoft SQL Server 2005 Analysis Services(SSAS)通过服务器和客户端技术的组合 提供联机分析处理(OLAP)和数据挖掘功能,并通过使用专用的开发和管理环境以及为设 计、创建、部署和维护商业智能应用程序而完善定义的对象模型进一步增强这些功能。 Analysis Services部署向导使用从Microsoft SQL Server 2005 Analysis Services(SSAS) 项目生成的XML输出文件作为输入文件。可以轻松的修改这些输入文件,以自定义Analysis Services项目的部署。 使用Analysis Services部署向导的操作步骤如下: 单击“开始”按钮,依次指向“所有程序”、Microsoft SQL Server 2005、Analysis Services,然后单击“部署向导”选项,即可打开“Analysis Services部署向导”对话框。 单击“下一步”按钮,依照提示进行操作即可。 2.4.4 SQL Server Configuration Manager配置工具 SQL Server Configuration Manager(配置管理器)是一种工具,用于管理与SQL Server 相关联的服务、配置SQL Server使用的网络协议以及从SQL Server客户端计算机管理网络连 接配置。SQL Server Configuration Manager是一个Microsoft管理控制台管理单元,可以从“开 始”菜单进行访问,也可以将其添加到其他任何Microsoft管理控制台显示中。Microsoft 管 理控制台(mmc.exe )使用Windows 安装目录下的System32 文件夹中的 SQLServerManager.msc文件打开SQL Server Configuration Manager。 SQL Server Configuration Manager集成了以下SQL Server 2000工具的功能: 选择项目类型。 选择项目模板。 设置项目名称、保 存位置和解决方案名 称。 43 第2章 Chapter 02 初识SQL Server 2005 y 服务器网络实用工具。 y 客户端网络实用工具。 y 服务管理器。 1. 服务配置 可以使用SQL Server Configuration Manager配置工具来管理和 配置SQL Server 2005的服务。操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005|“配置工具”| SQL Server Configuration Manager选项,打开SQL Server Configuration Manager窗口,如图2.23所示。 图 2.23 SQL Server Configuration Manager 窗口 在左侧窗口中,选择“SQL Server 2005服务” 选项,在右侧窗口中即可看到当前已经安装的SQL Server服务。在服务名称上右击,即可弹出一个快捷菜 单,如图2.24所示。通过其中的“启动”、“停止”、“暂 停”和“重新启动”等命令即可启动和停止相应的服 务。 双击某个服务,即可打开该服务的“SQL Server(MSSQLSERVER)属性”对话框,如图2.25所示。 默认打开的是“登录”选项卡,在该选项卡中,可以设置服务账户。也可以通过单击“服 务状态”下的按钮来启动或停止服务。 当前已经安装的SQL Server 服务 实讲实训 多媒体演示 多媒体演示参见配套 光盘中的\\视频\第2 章\服务配置.avi。 图 2.24 启动和停止服务 新概念 SQL Server 2005 教程 44 图 2.25 “SQL Server(MSSQLSERVER)属性”对话框 如果要设置服务的启动模式,则可以单击“服 务”标签,打开“服务”选项卡。选择“启动模式”选 项,然后单击右侧的下拉列表框,从出现的下拉列表中 可以选择服务的启动模式,如图2.26所示。 设置完成后,单击“确定”按钮,系统提示重 新启动服务,单击“是”按钮即可。 提 示 在“高级”选项卡中,可以进一步设置服务的启 动参数、转存目录,并可以设置是否发送错误报告和客 户反馈报告等。 2. 网络配置 通过SQL Server Configuration Manager配置工具,可以设置 SQL Server 2005的网络配置。操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 |“配置工具”| SQL Server Configuration Manager选项,打开 SQL Server Configuration Manager窗口。 在左侧窗口中,通过双击依次打开 “SQL Server 2005网络配置”|“MSSQLS- ERVER的协议”选项,在右侧窗口中即可看 到SQL Server 2005支持的网络协议,如图 2.27所示。 双击某个网络协议,即可打开该协 议的属性对话框,用户可以通过该对话框对 网络协议进行配置。例如,双击TCP/IP,即 可打开“TCP/IP属性”对话框,如图2.28所 单击这些按钮可以启 动或者停止服务。 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\第 2章\网络配置.avi。 图 2.26 “服务”选项卡 图 2.27 SQL Server 2005 支持的网络协议 45 第2章 Chapter 02 初识SQL Server 2005 示。 图 2.28 “TCP/IP 属性”对话框 3. 客户端配置 如果要在客户端连接远程的SQL Server 2005服务器,则需要在 客户端计算机上安装并配置网络协议。操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 |“配置工具”| SQL Configuration Manager选项,打开SQL Server Configuration Manager窗口。 在左侧窗口中,双击打开“SQL Native Client配置”,然后 双击“客户端协议”。在右侧窗口中即可看到客户端已经配置的网络协议,如图2.29所示。 图 2.29 SQL Server Configuration Manager 窗口 双击某个网络协议,即可打开该协议的属性对话框,用户可以通过该对话框对网 络协议进行配置。 2.4.5 性能工具 SQL Server 2005提供了SQL Server Profiler和数据引擎优化顾问两个性能工具。下面分 别进行介绍。 通过该选项卡可以设置 IP地址和端口等信息 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\第 2章\客户端配置.avi。 新概念 SQL Server 2005 教程 46 1. SQL Server Profiler Microsoft SQL Server Profiler是SQL跟踪的图形用户界面,用于监视SQL Server Data- base Engine或SQL Server Analysis Services的实例。可以捕获有关每个事件的数据并将其保 存到文件或表中供以后分析。例如,可以对生产环境进行监视, 了解哪些存储过程由于执行速度太慢影响了性能。 启动和使用SQL Server Profiler的操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 |“性能工具”| SQL Server Profiler选项,打开SQL Server Profiler窗口。 提 示 通过下面两种方式也可以打开SQL Server Profiler窗口:在SQL Server Management Studio的“工具”菜单上,单击SQL Server Profiler;在数据库引擎优化顾问的“工具”菜 单上,单击SQL Server Profiler。 在“文件”菜单上,选择“新建跟踪”选项,打开“连接到服务器”对话框,选 择要连接的服务器,并设置相应的登录模式。 单击“连接”按钮,打开“跟踪属性”对话框,如图2.30所示。在“常规”选项 卡中,可以设置“跟踪名称”、“使用模板”和“启用跟踪起止时间”等选项。 图 2.30 “跟踪属性”对话框 单击“事件选择”标签,打开“事件选择”选项卡,如图2.31所示。在该选项卡 中,可以设置要跟踪的事件和事件列。 设置完成后,单击“运行”按钮即可开始跟踪。 实讲实训 多媒体演示 多媒体演示参见配套光 盘中的\\ 视频\ 第 2 章 \Profiler.avi。 47 第2章 Chapter 02 初识SQL Server 2005 图 2.31 “事件选择”选项卡 2. 数据库引擎优化顾问 借助Microsoft SQL Server 2005数据库引擎优化顾问,用户不必精通数据库结构或 Microsoft SQL Server的精髓,即可选择和创建索引、索引视图和分区的最佳集合。 数据库引擎优化顾问分析一个或多个数据库的工作负荷和物理实现。工作负荷是对要 优化的一个或多个数据库执行的一组Transact-SQL语句。在优化数据库时,数据库引擎优化 顾问将使用跟踪文件、跟踪表或Transact-SQL脚本作为工作负荷输入。可以在SQL Server Management Studio中使用查询编辑器创建Transact-SQL脚本工作负荷。可以通过使用SQL Server Profiler中的优化模板来创建跟踪文件和跟踪表工作负荷。 启动和使用数据库引擎优化顾问的操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 |“性能工具”| “数据库引擎优化顾问”选项,打开“连接服务器”对话框。 选择要连接的服务器,并设置相应的登录模式。然后单击“连接”按钮,连接成 功后,弹出Database Engine Tuning Adviser窗口,如图2.32所示。 图 2.32 Database Engine Tuning Adviser 窗口 新概念 SQL Server 2005 教程 48 在“常规”选项卡中,选择“工作负荷”中的“文件”或“表”选项,并设置“用 于工作负荷分析的数据库”。其中工作负荷由保存在文件或表中Transact-SQL脚本或SQL Server Profiler跟踪组成。 在“优化选项”选项卡中,可以设置用于优化的一些选项。设置完成后,单击工 具栏中的“开始分析”按钮,即可开始优化分析。 除了上面的启动数据库引擎优化顾问操作步骤外,还可以在SQL Server Management Studio窗口或者SQL Server Profiler窗口的“工具”菜单中,单击“数据库引擎优化顾问” 来启动数据库引擎优化顾问。 另外,也可以在SQL Server Management Studio查询编辑器中,直接选择输入的 Transact-SQL语句,然后右击鼠标,在弹出的快捷菜单中,选择“在数据库引擎优化顾问中 分析查询”选项。此时将打开数据库引擎优化顾问图形用户界面,并将该脚本作为XML文 件工作负荷导入。可以指定会话名称和优化选项,以将选定的Transact-SQL查询作为工作负 荷进行优化。 提 示 可以使用命令行工具程序dta.exe来实现数据库引擎优化顾问的功能。 2.4.6 文档和教程 Microsoft SQL Server联机丛书是Microsoft SQL Server 2005的文档集。联机丛书涵盖了 有效使用SQL Server所需的概念和过程。联机丛书还包括了使用SQL Server存储、检索、报 告和修改数据时所使用的语言和编程接口的参考资料。 打开和使用联机丛书的操作过程如下: 打开“开始”菜单,依次选择“所有程序”| Microsoft SQL Server 2005 |“文档和 教程”| “SQL Server 联机丛书”选项,即可打开“联机丛书-Microsoft SQL Server 2005” 窗口,如图2.33所示。 图 2.33 “联机丛书-Microsoft SQL Server 2005”窗口 可以按照目录来查找需要的内容;也可以通过“搜索”选项卡来寻找需要的内容。 49 第2章 Chapter 02 初识SQL Server 2005 2.5 管理SQL Server服务器 服务器是SQL Server数据库管理系统的核心,管理服务器可以通过SQL Server Management Studio管理平台来完成。 2.5.1 管理服务器组 在一个客户端上可以同时管理多个SQL Server服务器。可以将多 个SQL Server服务器分类汇总到不同的服务器组中,以方便管理。 创建和使用服务器组的操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 | SQL Server Management Studio 选项,打开SQL Server Management Studio窗口。 连接到服务器,然后在打开的“已注册的服务器”窗口中, 右击鼠标,在快捷菜单中选择“新建”|“服务器组”命令,打开“新建服务器组”对话框, 如图2.34所示。 图 2.34 “新建服务器组”对话框 设置完成后,单击“保存”按钮,即可创建一个服务器组,如图2.35所示。这里 创建的服务器组是SLQSERVER1。 图 2.35 新创建的服务器组 输入服务器 组名称。 选择新服务器 组要放置的位置。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第2章\管理服 务器组.avi。 新概念 SQL Server 2005 教程 50 如果要将已注册的服务器移动到该服务器组中,则可右击服务器名称,在弹出的 快捷菜单上,选择“移到”选项,打开“移动服务器注册”对话框。选择服务器组名称, 如图2.36所示。 单击“确定”按钮,即可将服务器liuasus移到服务器组SQLSERVER1中,如图2.37 所示。 图 2.36 “移动服务器注册”对话框 图 2.37 将服务器移到服务器组中 2.5.2 注册服务器 在SQL Server Management Studio中注册服务器可以存储服务器连接信息,以供将来连 接时使用。在注册服务器时必须指定: y 服务器的类型,在Microsoft SQL Server 2005中,可以注册下列类型的服务器:数 据库引擎、Analysis Services、Reporting Services、Integration Services和SQL Server Mobile。 y 服务器的名称。 y 登录到服务器时使用的身份验证的类型。 注册服务器的操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 | SQL Server Management Studio选项,打开SQL Server Management Studio窗口。 在“已注册的服务器”窗口中,右击鼠标,在快捷菜单的“新 建”选项中,选择“服务器注册”选项,打开“新建服务器注册”对 话框,如图2.38所示。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第2章\注册服 务器.avi。 51 第2章 Chapter 02 初识SQL Server 2005 图 2.38 “新建服务器注册”对话框 设置完成后,单击“测试”按钮,测试到新建服务器的连接。如果配置成功,则 会打开“新建服务器注册”对话框,提示连接测试成功,如图2.39所示。 图 2.39 提示连接测试成功 测试成功后,单击“保存”按钮,保存新建的服务器注册。 如果要修改服务器注册,则可以右击要修改的服务器实例,然后选择快捷菜单中 的“属性”选项,在打开的“编辑服务器注册属性”对话框中,用户可以修改服务器的身 份验证模式和服务器名称等信息。 如果要删除服务器实例,则可以右击要删除的服务器实例,然后选择快捷菜单中 的“删除”选项,在弹出的确认删除对话框中单击“是”按钮,即可删除服务器实例。 2.6 课堂演练 在服务器上注册一个SQL Server服务器。操作步骤如下: 打开SQL Server Management Studio。 在“连接属性” 选项卡中,可以设置 网络协议以及连接 到的数据库等选项。 选择服务器 或直接输入服 务器名。 选择身份验 证模式。 新概念 SQL Server 2005 教程 52 在“已注册的服务器”窗口中,右击鼠标,在快捷菜单的“新建”选项中,选择 “服务器注册”选项,打开“新建服务器注册”对话框。设置服务器名称和身份验证模式。 单击“测试”按钮,测试到新建服务器的连接。如果配置成功,则会打开“新建 服务器注册”对话框,提示连接测试成功。 测试成功后,单击“保存”按钮,保存新建的服务器注册。 2.7 小结 本章介绍了安装SQL Server 2005的安装选项及具体安装步骤,并对SQL Server 2005的 组件功能、SQL Server Management Studio管理平台、性能工具、配置工具、Analysis Services 和服务器的管理等进行了介绍。 在SQL Server 2005中的安装中,关键是要理解各个选项的设置,主要包括服务账户和 验证模式等设置。 SQL Server 2005是一个功能很强的数据库管理系统,它包含了几个用于数据库以及安 全性配置的工具。在本章中,对这些管理工具和服务器的管理进行了简要介绍,使读者在 使用SQL Server 2005以前有一个全面的认识。 2.8 课后练习 2.8.1 简答题 (1)简述服务账户的概念。 (2)简述SQL Server 2005的组件及其功能。 (3)SQL Server Management Studio的功能有哪些? 2.8.2 操作题 (1)安装SQL Server 2005,了解安装步骤和注意事项。 (2)试着使用SQL Server 2005的工具和教程。 第 3 章 数据库和表 03 Chapter 本章导读: ” 数据库文件 ” 页和区的概念 ” 事务日志 ” 查看数据库属性 ” 数据库的建立 ” 数据库的删除 ” 表的建立 ” 表的删除 3.1 数据库存储结构 数据库的存储结构分为逻辑存储结构和物理存储结构。数据库的逻辑存储结构指的是 数据库的性质信息等。SQL Server数据库是由表、视图和索引等各种不同的数据库对象所 组成,它们分别存储数据库的特定信息,构成了数据库的逻辑存储结构。数据库的物理存 储结构则指的是磁盘上存储的数据库文件。 数据库文件由数据库文件和事务日志文件组成,保存在物理介质的NTFS分区或者FAT 分区上,它预先分配了将要被数据库和事务日志所使用的物理存储空间。 3.1.1 数据库文件和文件组 SQL Server 2005将数据库映射为一组操作系统文件。数据和日志信息从不混合在相同 的文件中,而且各文件仅在一个数据库中使用。文件组是命名的文件集合,用于帮助数据 布局和管理任务,例如备份和还原操作。 SQL Server 2005数据库具有3种类型的文件: y 主数据文件 主数据文件是数据库的起点,指向数据库中的其他文件。每个数据 库都有一个主数据文件。主数据文件的推荐文件扩展名是.mdf。 y 次要数据文件 除主数据文件以外的所有其他数据文件都是次要数据文件。某些 数据库可能不含有任何次要数据文件,而有些数据库则含有多个次要数据文件。 次要数据文件的推荐文件扩展名是.ndf。 y 日志文件 日志文件包含着用于恢复数据库的所有日志信息。每个数据库必须至 少有一个日志文件,当然也可以有多个。日志文件的推荐文件扩展名是 .ldf。 新概念 SQL Server 2005 教程 54 注 意 SQL Server 2005不强制使用.mdf、.ndf和.ldf 文件扩展名,但使用它们有助于标识文 件的各种类型和用途。 在SQL Server 2005中,数据库中所有文件的位置都记录在数据库的主文件和master数 据库中。大多数情况下,数据库引擎使用master数据库中的文件位置信息。但是,在以下 情况中,数据库引擎使用主文件中的文件位置信息来初始化master数据库中的文件位置项: y 使用带有FOR ATTACH 或 FOR ATTACH_REBUILD_LOG 选项的CREATE DATABASE语句来附加数据库时。关于CREATE DATABASE语句的详细使用,可 以参看附录B。 y 从SQL Server 2000版或7.0版升级到SQL Server 2005时。 y 还原master数据库时。 为便于数据库文件的分配和管理,可以将数据库对象和文件一起分成文件组。有两种 类型的文件组: y 主文件组 主文件组包含主数据文件和任何没有明确分配给其他文件组的其他文 件。系统表的所有页均分配在主文件组中。 y 用户定义文件组 用户定义文件组是通过在CREATE DATABASE或ALTER DATABASE语句中使用FILEGROUP关键字指定的任何文件组。 一个文件不可以是多个文件组的成员。表、索引和大型对象数据可以与指定的文件组 相关联。在这种情况下,它们的所有页将被分配到该文件组,或者对表和索引进行分区。 已分区表和索引的数据被分割为单元,每个单元可以放置在数据库中的单独文件组中。 每个数据库中均有一个文件组被指定为默认文件组。如果创建表或索引时未指定文件 组,则将假定所有页都从默认文件组分配。一次只能有一个文件组作为默认文件组。 注 意 日志文件不包括在文件组内。日志空间与数据空间分开管理。 SQL Server 2005文件可以从它们最初指定的大小开始,随数据的增加而自动增长。在 定义文件时,可以指定一个特定的增量。每次填充文件时,其大小均按此增量来增长。如 果文件组中有多个文件,则它们在所有文件被填满之前不会自动增长。填满后,这些文件 会循环增长。 每个文件还可以指定一个最大大小。如果没有指定最大大小,文件可以一直增长到用 完磁盘上的所有可用空间。如果SQL Server作为数据库嵌入某应用程序,而该应用程序的 用户无法迅速与系统管理员联系,则此功能就特别有用。用户可以使文件根据需要自动增 长,以减轻监视数据库中的可用空间和手动分配额外空间的管理负担。 3.1.2 页和区 在创建数据库对象时,SQL Server会使用一些特定的数据结构给数据对象分配空间, 即页和区。它们和数据库及其文件间的关系如图3.1所示。 55 第3章 Chapter 03 数据库和表 图 3.1 数据库的存储结构 1. 页 SQL Server中数据存储的基本单位是页(page)。为数据库中的数据文件(.mdf或.ndf) 分配的磁盘空间可以从逻辑上划分成页(从0到n连续编号)。磁盘I/O操作在页级执行。也 就是说,SQL Server读取或写入所有数据页。 SQL Server中的所有信息都存储在页上,页是数据库中使用的最小数据单元。每一个 页存储8KB(8192字节)的信息,所有的页都包含一个132字节的页面头,这样就留下8060 字节存储数据。页头被SQL Server用来唯一地标识存储在页中的数据。 SQL Server使用如下几种类型的页: y 分配页面 用于控制数据库中给表和索引分配的页面。 y 数据和日志页面 用于存储数据库数据和事务日志数据。数据存储在每个页面的 数据行中,每一行的最大值为8060个字节。SQL Server不允许跨页面存储。 y 索引页面 用于存储数据库中的索引数据。 y 分发页面 用于存储数据库中有关索引的信息。 y 文本/图像页面 用于存储大量的文本或者二进制的对象(BLOB),例如,图像。 在SQL Server数据页上,数据行紧接着标头按顺序放置。页的末尾是行偏移表,对于 页中的每一行,每个行偏移表都包含一个条目。每个条目记录对应行的第一个字节与页首 的距离。行偏移表中的条目的顺序与页中行的顺序相反,如图3.2所示。 数据库 数据文件.mdf 或者.ndf 日志文件.ldf 区(8个连续页面) 表、索引 数据页(8KB) 最大行长度为8080字节 新概念 SQL Server 2005 教程 56 图 3.2 SQL Server 数据页 在SQL Server 2005中,行不能跨页,但是行的部分可以移出行所在的页,因此行实际 可能非常大。页的单个行中的最大数据量和开销是8 060字节(8 KB)。但是,这不包括用 Text/Image页类型存储的数据。在SQL Server 2005中,包含varchar、nvarchar、varbinary或 sql_variant列的表不受此限制的约束。当表中的所有固定列和可变列的行的总大小超过限制 的8 060字节时,SQL Server将从最大长度的列开始动态将一个或多个可变长度列移动到 ROW_OVERFLOW_DATA分配单元中的页。每当插入或更新操作将行的总大小增大到超 过限制的8 060字节时,将会执行此操作。将列移动到ROW_OVERFLOW_DATA分配单元 中的页后,将在IN_ROW_DATA分配单元中的原始页上维护24字节的指针。如果后续操作 减小了行的大小,SQL Server会动态将列移回到原始数据页。 2. 区 区(extent)是由8个连续的页面组成的数据结构,大小为8×8KB=64KB。当创建一 个数据库对象时,SQL Server会自动以区为单位给它分配空间。每一个区只能包含一个数 据库对象。 区是表和索引分配空间的单位,如果在一个新建的数据库中创建一个表和两个索引, 并且表中只包含一笔记录,则总共占用3×64KB=192KB的空间。 提 示 所有的SQL Server数据库都包含这些数据库结构,简单地说,一个数据库是由文件组 成,文件是由区组成,区是由页面组成。 为了使空间分配更有效,SQL Server不会将所有区分配给包含少量数据的表。SQL Server有两种类型的区: y 统一区 由单个对象所有。区中的所有8页只能由所属对象使用。 y 混合区 最多可由8个对象共享。区中8页的每页可由不同的对象所有。 混合区和统一区如图3.3所示。 行偏移量 Microsoft SQL Server数据页 标头 数据行1 数据行2 数据行3 可用空间 57 第3章 Chapter 03 数据库和表 图 3.3 混合区和统一区(table 表示表,index 表示索引) 通常从混合区向新表或索引分配页。当表或索引增长到 8 页时,将变成使用统一区进 行后续分配。如果对现有表创建索引,并且该表包含的行足以在索引中生成 8 页,则对该 索引的所有分配都使用统一区进行。 3.1.3 事务日志 每个SQL Server 2005数据库都具有事务日志,用于记录所有事务以及每个事务对数据 库所做的修改。事务日志是数据库的关键组件,如果系统出现故障,它就是近期数据的唯 一源。 在创建数据库的时候,事务日志也会随着被创建。事务日志存储在一个单独的文件上。 在修改写入数据库之前,事务日志会自动记录对数据库对象所做的修改。这是SQL Server 的一个重要的容错特性,它可以有效地防止数据库的损坏,维护数据库的完整性。 1. 事务日志支持的操作 事务日志支持以下操作: y 恢复个别的事务 如果应用程序发出ROLLBACK语句,或者数据库引擎检测到错 误(例如失去与客户端的通信),就使用日志记录回滚未完成的事务所做的修改。 y SQL Server启动时恢复所有未完成的事务 当运行SQL Server的服务器发生故障 时,数据库可能处于这样的状态:还没有将某些修改从缓存写入数据文件,在数 据文件内有未完成的事务所做的修改。当启动SQL Server实例时,它对每个数据库 执行恢复操作。前滚日志中记录的、可能尚未写入数据文件的每个修改。在事务 日志中找到的每个未完成的事务都将回滚,以确保数据库的完整性。 y 将还原的数据库、文件、文件组或页前滚到故障点 在硬件丢失或磁盘故障影响 到数据库文件后,可以将数据库还原到故障点。首先还原上一次的完整备份和差 异备份,然后将事务日志备份后续序列还原到故障点。当还原每个日志备份时, 数据库引擎 重新应用日志中记录的所有修改,以回滚所有事务。当最后的日志备 份还原后,数据库引擎将使用日志信息回滚到该点未完成的所有事务。 y 支持事务复制 日志读取器代理程序监视已为事务复制配置的每个数据库的事务 日志,并将已设复制标记的事务从事务日志复制到分发数据库中。 y 支持备用服务器解决方案 备用服务器解决方案、数据库镜像和日志传送高度依 赖于事务日志。在日志传送方案中,主服务器将主数据库的活动事务日志发送到 新概念 SQL Server 2005 教程 58 一个或多个目标服务器。每个辅助服务器将该日志还原为其本地的辅助数据库。 在数据库镜像方案中,数据库(主体数据库)的每次更新都在独立的、完整的数 据库(镜像数据库)副本中立即重新生成。主体服务器实例立即将每个日志记录 发送到镜像服务器实例,镜像服务器实例将传入的日志记录应用于镜像数据库, 从而将其继续前滚。有关详细信息,请参阅数据库镜像概述。 SQL Server Database Engine的事务日志具有如下特征: y 事务日志是作为数据库中的单独的文件或一组文件实现的。日志缓存与数据页缓 存分开管理,从而使数据库引擎内的编码更简单、更快速和更可靠。 y 日志记录和页的格式不必遵守数据页的格式。 y 事务日志可以在几个文件上实现。通过设置日志的FILEGROWTH值可以将这些文 件定义为自动扩展。这样可减少事务日志内空间不足的可能性,同时减少管理开 销。 y 重用日志文件中空间的机制速度快且对事务吞吐量影响最小。 2. 事务日志提供容错的机制 在SQL Server中,事务是指一次完成的操作的集合,虽然一个事务中可能包含了很多 的SQL语句,但是在处理上,它们就像是一个操作一样。为了维护数据库的完整性,它们 必须彻底完成或者根本不执行。如果一个事务只是部分执行,则数据库将受到损坏。 SQL Server使用数据库的事务日志来防止没有完成的事务破坏数据。具体步骤如下: 用户执行修改数据库对象的任务。 当这个事务开始时,在事务日志中会记录一个事务开始标志,并将与此操作相关 的数据读入缓冲区。 在日志中记录每一个操作,然后在日志中记录一个提交事务的标志。每一个事务 都会以这种方式记录在事务日志中,这些记录立即写到硬盘上。 在缓冲区中修改响应的数据。这些数据一直在缓冲区中,直到检查点进程发生(定 期发生),才会写到硬盘上。同时,也会在事务日志中写入“所有已经完成的事务已经作 用于数据库”,即在事务日志中写入一个检查点标志。这个标志用于在数据库恢复过程中 确定哪个事务已经作用于数据库了。 如果服务器在已经完成了这个事务(这些事务的操作信息已经写入事务日志中) 但还没有将缓冲区中的数据写入物理硬盘的情况下(检查点进程尚未触发)失效了或者在 服务器恰好处理了部分事务的情况下数据库服务器失效了,那么在这两种情况下,数据库 都不会被破坏。在服务器恢复正常后,SQL Server会开始一个恢复过程,检查数据库和事 务日志,如果事务日志中的事务还没有在数据库中生效,则会在此时作用于数据库(前滚); 如果发现部分事务还没有完成,则将这个事务在数据库中的作用去掉(回滚)。这个过程是 自动进行的。数据库完整性信息都由事务日志来完成,从而从本质上增强了SQL Server的 容错性能。 59 第3章 Chapter 03 数据库和表 3.2 查看数据库 在建立一个实际的数据库之前,需要了解在SQL Server中怎样查看数据库的属性,包 括表的结构和内容、关联图、视图、存储过程和用户角色等。 3.2.1 查看系统数据库 新安装SQL Server 2005后,默认包含4个系统数据库:master数据 库、model数据库、msdb数据库和tempdb数据库。 查看系统数据库的操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 | SQL Server Management Studio选项,打开“连接到服务器”对 话框,进行相应设置后,单击“连接”按钮,连接到相应的服务器。 在连接成功后弹出的“对象资源管理器”窗口中,依次打开“数据库”|“系统数 据库”选项,即可看到4个系统数据库,如图3.4所示。 图 3.4 系统数据库 下面对这些系统数据库进行介绍。 1. master 数据库 master数据库记录了SQL Server系统的所有系统级别信息。它记录所有的登录账户和系 统配置设置。它还记录所有其他的数据库,其中包括数据库文件的位置。master数据库记 录SQL Server的初始化信息,它始终有一个可用的最新master数据库备份。因此,如果 master 数据库不可用,则SQL Server无法启动。 注 意 在SQL Server 2005 中,系统对象不再存储在master数据库中,而是存储在Resource 数据库中。Resource 数据库是只读数据库,它包含了SQL Server 2005中的所有系统对象。 SQL Server系统对象(例如sys.objects)在物理上持续存在于Resource数据库中,但在逻辑 上,它们出现在每个数据库的sys架构中。 系统数据库 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\查看系 统数据库.avi。 新概念 SQL Server 2005 教程 60 2. tempdb 数据库 tempdb数据库是连接到SQL Server实例的所有用户都可用的全局资源,保存所有的临 时表和临时存储过程。它还满足任何其他的临时存储要求,例如,存储SQL Server生成的 工作表。所有连接到系统的用户的临时表和存储过程都存储在该数据库中。该数据库在 SQL Server 每次启动时都重新创建,因此该数据库在系统启动时总是干净的。临时表和存 储过程在连接断开时自动除去,而且当系统关闭后将没有任何连接处于活动状态,因此 tempdb数据库中没有任何内容会从SQL Server的一个会话保存到另一个会话。 注 意 默认情况下,在SQL Server运行时,tempdb数据库会根据需要自动增长。不过,与其 他数据库不同,每次启动数据库引擎时,它会重置为其初始大小。如果为tempdb 数据库 定义的大小较小,则每次重新启动 SQL Server时,将tempdb数据库的大小自动增加到支 持工作负荷所需的大小这一工作可能会成为系统处理负荷的一部分。为避免这种开销,可 以使用ALTER DATABASE增加tempdb数据库的大小。ALTER DATABASE将在后面介绍。 3. model 数据库 model数据库用作在系统上创建的所有数据库的模板。当创建数据库时,新数据库的第 一部分通过复制model数据库中的内容创建,剩余部分由空页填充。由于SQL Server每次启 动时都要创建tempdb数据库,model数据库必须一直存在于SQL Server系统中。 如果修改 model 数据库,之后创建的所有数据库都将继承这些修改。 4. msdb 数据库 msdb数据库供SQL Server代理程序调度警报和作业以及记录操作员时使用。 3.2.2 查看用户数据库 利用SQL Server Management Studio可以查看数据库的内容,包括数据库的所有者、建 立时间、大小、可用空间、表和索引等。 下面以AdventureWorks数据库为例,来介绍数据库内容的查看。AdventureWorks数据库 是SQL Server 2005自带的示例数据库。 在默认安装选项的情况下,SQL Server 2005安装程序并不安装该示例数据库。要安装 该示例数据库,在安装过程中,在“要安装的组件”页上选择“工作站组件、联机丛书和 开发工具”,单击“高级”按钮,然后打开“联机丛书和示例”选项,选择“示例”选项, 然后打开“数据库”,然后选择要安装的示例数据库即可。如果安装 已经完成,可以通过“添加或删除程序”来安装AdventureWorks数据 库。 查看数据库的操作步骤如下: 打开“开始”菜单,依次选择“程序”| Microsoft SQL Server 2005 | SQL Server Management Studio选项,打开“连接到服务器”对 话框,进行相应设置后,单击“连接”按钮,连接到相应的服务器。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\查看用 户数据库.avi。 61 第3章 Chapter 03 数据库和表 在“对象资源管理器”窗口中,打开“数据库”选项,然后打开AdventureWorks 数据库,即可看到AdventureWorks数据库及其包含的内容,如图3.5所示。 图 3.5 AdventureWorks 数据库 在AdventureWorks数据库上右击,选择快捷菜单中的“属性”选项,弹出“数据 库属性-AdventureWorks”对话框,如图3.6所示。 图 3.6 “数据库属性-AdventureWorks”对话框 在该对话框中,默认显示的是“常规”选项卡,各选项的含义如下: y 数据库上次备份日期 显示数据库上次备份的日期。 y 数据库日志上次备份日期 显示数据库事务日志上次备份的日期。 AdventureWorks 数 据 库及其包含的内容 数据库选项的分类 新概念 SQL Server 2005 教程 62 y 名称 显示数据库的名称。 y 所有者 显示数据库所有者的名称。可以在“文件”页上更改所有者。 y 创建日期 显示数据库的创建日期和时间。 y 大小 显示数据库的大小(MB)。 y 可用空间 显示数据库中的可用空间(MB)。 y 用户数 显示连接到该数据库的用户数。 y 排序规则 显示用于该数据库的排序规则。可以在“文件”页上更改排序规则。 在“选择页”窗口中,单击“文件”选项,即可看到AdventureWorks数据库的数 据库文件和日志文件的设置,如图3.7所示。 图 3.7 AdventureWorks 数据库的数据库文件和日志文件 各选项的含义如下: y 数据库名称 添加或显示数据库的名称。 y 所有者 通过从列表中进行选择来指定数据库的所有者。 y 使用全文索引 选中此选项将对数据库启用全文索引。取消此选项将对数据库禁 用全文索引。 y 数据库文件 添加、查看、修改或删除相关联数据库的数据库文件。 数据库文件具有以下属性: y 逻辑名称 输入或修改文件的名称。 y 文件类型 从列表中选择文件类型。文件类型可以是“数据”或“日志”。 y 文件组 从列表中为文件选择文件组。默认情况下,文件组为PRIMARY。通过选 择“<新文件组>”,然后在“新建文件组”对话框中输入有关文件组的信息,可 以创建新的文件组。也可以在“文件组”页上创建新的文件组。 y 初始大小 输入或修改文件的初始大小(MB)。此设置的默认值为“模型”数据 单击该按钮可以将新文 件添加到数据库中 单击该按钮可 以将文件从数 据库中删除 单击该按钮可以设置数据 库文件的自动增量设置 63 第3章 Chapter 03 数据库和表 库的初始大小值。 y 自动增长 选择或显示文件的自动增长属性,这些属性控制文件在达到其最大文 件大小时的扩展方式。若要编辑自动增长值,可单击所需文件的自动增长属性旁 的编辑按钮,再更改“更改自动增长”对话框中的相应值。此设置的默认值为“模 型”数据库的自动增长值。 y 路径 显示所选文件的路径。若要指定新文件的路径,可单击文件路径旁的编辑 按钮,再导航到目标文件夹。 y 文件名 显示文件的名称。 提 示 在从数据库中删除文件时,要求文件为空。否则无法删除文件。无法删除主数据文 件和日志文件。 要查看数据库中表的信息,可以单击AdventureWorks数据库中的“表”选项,在 右侧窗口中即可看到数据库中表的信息,如图3.8所示。 图 3.8 数据库中表的信息 3.2.3 查看表之间的关系图 关系图是用来记录数据库中表之间的相互关联情况的。在SQL Server中,一个数据库可以有多个关系图。要查看表之间的关系,首 先要创建关系图,其操作步骤如下: 在AdventureWorks数据库下面,右击“数据库关系图”选项, 在弹出的快捷菜单中选择“新建数据库关系图”选项,打开“添加表” 对话框。选择Employee 、 EmployeeAddress 和 EmployeeDepartmentHistory 3个表,如图3.9所示。 系统表,在数据 库被新建立时 就产生的 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\查看表 关系.avi。 新概念 SQL Server 2005 教程 64 图 3.9 选择要查看关系图的表 单击“添加”按钮,然后单击“关闭”按钮,即可看到代表3个表之间的关系图, 如图3.10所示。 图 3.10 3 个表之间的关系图 可以保存这个关系图,便于下次打开查看。单击工具栏上的“保存”按钮,打开 “选择名称”对话框,在文本框中输入关系图的名称,如图3.11所示。 图 3.11 “选择名称”对话框 单击“确定”按钮,即可保存当前关系图。在“对象资源管理器”的“数据库关 系图”下面,会显示该关系图。 3.2.4 查看表的结构和内容 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第3章\查看表的结 构和内容.avi。 65 第3章 Chapter 03 数据库和表 表是数据库中存放数据的地方,在SQL Server Management Studio中,可以很方便地查 看表的结构和表的内容。具体操作步骤如下: 打开AdventureWorks数据库,选择“表”,进而在要查看的表上右击鼠标(这里 查看表Employee的结构),选择“修改”命令,如图3.12所示。 图 3.12 选择“修改”命令 此时,会打开Employees表的结构窗口,如图3.13所示。 图 3.13 Employee 表的结构 提 示 新建一个表也是通过这个窗口来完成的,也可以在建立一个表后,通过此窗口来修 选择此项 字段名称 字段的数据类型(字段长度) 字段是否可以为空 字段的其他属 性设置 新概念 SQL Server 2005 教程 66 改表的结构。 要查看表的内容,在图3.12所示的快捷菜单上,选择“打开表”命令,即可查看 选项表的内容。Employee表的内容如图3.14所示。 图 3.14 Employee 表的内容 3.2.5 查看视图 视图(Views)是一种虚拟表,它的所有数据均来自表,本身并不存储数据。视图的记 录数据由某些表(一般是多个)的某些字段组成。视图的查看和表的 查看类似,其具体步骤如下: 在SQL Server Management Studio窗口中,打开Adventure- Works数据库。选择“视图”选项,然后在右侧窗口中选择要查看的 视图(这里查看vEmployeeDepartment视图),并右击鼠标。在弹出 的快捷菜单中选择“修改”命令。 此时,可打开视图的结构(设计)窗口,如图3.15所示。上 面部分显示了视图所包含的表,表中每一个字段的前面有一个复选框,处于选中状态表示 视图包含该字段。 如果要查看视图内容,可在视图上右击鼠标,在打开的快捷菜单中选择“打开视 图”选项,即可看到视图的内容,如图3.16所示。 注 意 由图3.16可看到,视图看起来和表一样,但是它的数据是来自所使用的表,本身并不 存储数据。 字段名称 表的多笔记录 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\查看视 图.avi。 该视图包含4个表 67 第3章 Chapter 03 数据库和表 图 3.15 视图的结构 图 3.16 视图的内容 3.2.6 查看存储过程 存储过程是预先使用SQL语言编写的,经过SQL Server编译后,存 储在SQL Server中的程序,因此执行效率比较高,而且可以重复调用。 下面仍以AdventureWorks数据库为例,介绍存储过程的查看。具 体操作步骤如下: 在SQL Server Management Studio窗口中,打开Adventure- Works数据库。选择“可编程性”|“存储过程”选项,即可看到Adventure- Works数据库所包含的存储过程,如图3.17所示。 处于选中状 态表示视图 包含该字段 字段名称 字段所 在的表 建立该视图的 SQL语句 当前记录/总记录数 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\查看存 储过程.avi。 新概念 SQL Server 2005 教程 68 图 3.17 AdventureWorks 数据库包含的存储过程 在左侧窗口中右击要查看的存储过程,例如uspGetEmployeeManagers存储过程, 在打开的快捷菜单中,选择“修改”选项,即可打开该存储过程的SQL语句窗口,如图3.18 所示。 图 3.18 uspGetemployeeManagers 存储过程的 SQL 语句窗口 关闭SQL语句窗口,在存储过程上双击鼠标,即可看到存储过程的输入参数和返 回值,如图3.19所示。 在存储过程上右击鼠标,在打开的快捷菜单中选择“属性”命令,即可打开存储 过程的属性窗口,如图3.20所示。在此窗口中显示了存储过程的创建日期和名称等信息。 提 示 系统内置了很多的存储过程以及扩充存储过程,可以使用这些存储过程来协助维护 数据库,也可以使用自己创建的存储过程。存储过程的创建和使用将在第9章中详细介绍。 69 第3章 Chapter 03 数据库和表 图 3.19 存储过程的输入参数和返回值 图 3.20 存储过程的属性窗口 3.2.7 查看用户和角色 用户(User)是对数据库有存取权限的使用者。角色(Roles)是 指一组数据库用户的集合(和Windows中的用户组类似)。数据库中 的角色可以根据需要添加。用户如果被加入到某一角色,则将具有该 角色所拥有的权限。 查看数据库的用户和角色的具体操作步骤如下: 在SQL Server Management Studio窗口中,打开Adventure- Works数据库。选择“安全性”|“用户”选项,即可看到数据库包含 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\查看用 户和角色.avi。 新概念 SQL Server 2005 教程 70 的用户,如图3.21所示。 图 3.21 AdventureWorks 数据库的用户 由图3.21 可看到,AdventureWorks 数据库目前有4 个用户:guest 、 sys 、 dbo 和 INFORMATION_SCHEMA。其中dbo的登录名为sa。 双击dbo用户,即可打开“数据库用户-dbo”对话框,如图3.22所示。上部显示了 用户使用的用户名以及登录名,在下面的“此用户拥有的架构”列表框中,可以设置用户 所拥有的架构;在下面的“数据库角色成员身份”列表框中,可以设置用户所属的角色。 图 3.22 用户 dbo 的属性 提 示 在“数据库角色成员”列表框中,显示的是数据库中所包含的角色,每一角色前面 有一复选框,如果选中,表示用户具有该角色所拥有的权限。另外,关于架构的内容,可 以参考3.2.7节的内容。 单击“确定”按钮,关闭“数据库用户-dbo”对话框。要查看数据库的角色,可 71 第3章 Chapter 03 数据库和表 在左侧窗口中选择“角色”|“数据库角色”选项。右侧窗口中即可显示出AdventureWorks 数据库所包含的数据库角色,如图3.23所示。 图 3.23 数据库的角色 双击要查看的数据库角色,例如db_owner,可显示角色的属性,如图3.24所示。 图 3.24 数据库角色的属性 提 示 应用程序角色是一个数据库主体,它使应用程序能够使用其自身及类似用户的特权 来运行。使用应用程序角色,可以只允许通过特定应用程序连接的用户访问特定数据。与 数据库角色不同的是,应用程序角色默认情况下不包含任何成员,而且是非活动的。因为 应用程序角色是数据库级别的主体,所以它们只能通过其他数据库中授予guest用户账户的 权限来访问这些数据库。因此,任何已禁用的guest用户账户的数据库对其他数据库中的应 用程序角色都是不可访问的。 默认的10个数 据库角色 新概念 SQL Server 2005 教程 72 3.2.8 数据库架构 架构是单个用户所拥有的数据库对象的集合,这些对象形成单个命名空间。命名空间 是一组名称不重复的对象。例如,只有当两个表位于不同的架构中时才可以具有相同的名 称。数据库对象(例如,表)由架构所拥有,而架构由数据库用户或角色所拥有。当架构 所有者离开单位时,会在删除离开的用户之前将该架构的所有权移交给新的用户或角色。 例如,假设用户userA拥有架构schemaA,而表Table1、Table2为架构schemeA所拥有。 当用户userA离开单位时,则可以将schemaA的所有权移交给用于管理Table1和Table2表的 新用户userB。当userB拥有schemaA后,同时也拥有了对Table1和 Table2的所有权。 1. 查看数据库架构 查看数据库架构的具体操作步骤如下: 在SQL Server Management Studio窗口中,打开Adventure- Works数据库。选择“安全性”|“架构”选项,即可看到Adventrue Works 数据库所包含的架构,如图3.25所示。 图 3.25 AdventureWorks 数据库所包含的架构 在架构名称上双击,例如HumanResources,即可打开架构的属性窗口,如图3.26 所示。 要设置架构的权限,可以在左侧窗口中单击“权限”选项,打开“权限设置”界 面,如图3.27所示。 可以通过单击“添加”按钮为架构添加用户或者角色来设置架构的所有者。当架构被 新用户或者角色所拥有时,其所拥有的表等对象也将被新用户或角色所拥有。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\查看数 据库架构.avi。 73 第3章 Chapter 03 数据库和表 图 3.26 架构的属性窗口 图 3.27 架构权限设置 2. SQL Server 2005 中的用户架构分离 在SQL Server 2000中,数据库用户和架构是隐式连接在一起的。每个数据库用户都是 与该用户同名的架构的所有者。对象的所有者在功能上与包含它的架构所有者相同。因而, SQL Server 2000中的完全限定名称的“架构”也是数据库中的用户。因此,从SQL Server 2000 数据库中删除用户之前,管理员需要删除该用户所拥有的所有对象或更改这些对象的所有 新概念 SQL Server 2005 教程 74 者。以包含此对象的SQL Server 2000数据库为例: accounting.ap.george.reconciliation 此对象的所有者为用户“george”。如果管理员需要删除用户george,则必须先删除此 对象或更改此对象的所有者。在后一种情况下,可以按如下方式将其重命名: accounting.ap.sandra.reconciliation 转让对象的所有权也会更改其完全限定名称。引用accounting.ap.george.reconciliation 的任何代码必须经过更新以反映对名称所做的更改。 在SQL Server 2005中,架构独立于创建它们的数据库用户而存在。可以在不更改架构 名称的情况下转让架构的所有权。并且可以在架构中创建具有用户友好名称的对象,明确 指示对象的功能。例如,除了accounting.ap.sandra.reconciliation外,还可以创建名为 accounting.ap.invoice.reconciliation的架构。因为“invoice”不是用户,所以从数据库中删除 用户后,无需更改此名称。这就简化了数据库管理员和开发人员的工作。 将架构与数据库用户分离对管理员和开发人员而言有下列好处: y 多个用户可以通过角色成员身份或Windows组成员身份拥有一个架构。这扩展了允 许角色和组拥有对象的用户熟悉的功能。 y 极大地简化了删除数据库用户的操作。 y 删除数据库用户不需要重命名该用户架构所包含的对象。因而,在删除创建架构 所含对象的用户后,不再需要修改和测试显式引用这些对象的应用程序。 y 多个用户可以共享一个默认架构以进行统一名称解析。 y 开发人员通过共享默认架构可以将共享对象存储在为特定应用程序专门创建的架 构中,而不是DBO架构中。 y 可以用比早期版本中的粒度更大的粒度管理架构和架构包含的对象的权限。 y 完全限定的对象名称现在包含4个部分:server.database.schema和object。 SQL Server 2005还引入了“默认架构”的概念,用于解析未使用其完全限定名称引用 的对象的名称。在SQL Server 2000中,首先检查的是调用数据库用户所拥有的架构,然后 是DBO拥有的架构。在SQL Server 2005中,每个用户都有一个默认架构,用于指定服务器 在解析对象的名称时将要搜索的第一个架构。 3.3 数据库的建立和删除 在SQL Server中,建立数据库的方法不只一种,可以使用SQL Server Management Studio 直接建立,也可以使用SQL语言来创建数据库。关于SQL语言的使用则将在第5章介绍。 3.3.1 建立数据库 直接建立数据库是在SQL Server Management Studio窗口中进行的,大多数情况下,应 该使用这种方式来创建一个数据库,因为图形化界面比Transact-SQL更容易使用。若要创建 75 第3章 Chapter 03 数据库和表 数据库,必须确定数据库的名称、所有者、大小以及存储该数据库的文件和文件组。 在创建数据库之前,应注意下列事项: y 若要创建数据库,必须至少拥有CREATE DATABASE、CREATE ANY DATA- BASE或ALTER ANY DATABASE权限。 y 在SQL Server 2005中,对各个数据库的数据和日志文件设置了某些权限。如果这 些文件位于具有打开权限的目录中,那么以上权限可以防止文件被意外篡改。 y 创建数据库的用户将成为该数据库的所有者。 y 对于一个SQL Server实例,最多可以创建32 767个数据库。 y 数据库名称必须遵循为标识符指定的规则。标识符不能是Transact-SQL保留字。 SQL Server保留其保留字的大写和小写形式。并且不允许嵌入空格或其他特殊字 符。 y model 数据库中的所有用户定义对象都将复制到所有新创建的数据库中。可以向 model数据库中添加任何对象(例如,表、视图、存储过程和数据类型),以便将 这些对象包含到所有新创建的数据库中。 创建新数据库的具体操作步骤如下: 在SQL Server Management Studio中,选择“数据库”文件夹, 在上面右击鼠标,在弹出的快捷菜单上选择“新建数据库”命令。 此时,会打开“新建数据库”窗口。在“数据库名称”文本 框中输入新建数据库的名字,例如bookdb,如图3.28所示。 图 3.28 “新建数据库”窗口 在此输入新建数据库的名字,该名字 必须符合SQL Server命名规范 单击可以添加 数据库文件 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\新建数 据库.avi。 新概念 SQL Server 2005 教程 76 在“数据库文件”栏中,可以设置文件的名称、位置及大小。数据库文件的逻辑 名称默认与数据库名称相同,用户可以修改这个名字,而且,可以指定多个文件。在“路 径”一栏中,可以通过单击 按钮来指定文件所在的位置。 在“初始大小”一栏中,以MB为单位输入数据库文件的大小。 在“自动增长”一栏中,可以选择文件是否自动增长和是否有最大限制。单击bookdb 对应的 按钮,打开“更改bookdb的自动增长设置”对话框,如图3.29所示。如果选择了 “启用自动增长”复选框,表示数据库的数据容量超过了初始大小时,数据文件可以自动 增加。设置完成后,单击“确定”按钮。 图 3.29 “更改 bookdb 的自动增长设置”对话框 提 示 由于新建数据库是以model数据库为模板创建的,因此,其大小不可能低于2MB(这 里假定model数据库的大小为2MB,如 果 model数据库数据文件的大小为其他数值,则不能 低于该数值),并且必须以1M的整数倍来创建。另外,数据库大小虽然可以自动增长,但 是增长后会造成数据库在磁盘中存放不连续,容易降低数据库的效率,因此建议先估算数 据库所需容量,再一次给定适当的大小。 在“选项页”栏中,选择“选项”选项,打开“新建数据库”的选项设置窗口, 如图3.30所示。在“排序规则”下拉列表框中,可以选择要使用的排序规则。不过,大多 数情况下,选择“(服务器默认值)”即可满足要求。在“恢复模式”列表框中,可以选 择数据库发生损坏时的恢复模式。在“其他选项”栏中,可以设置其他数据库选项。 同样,在“选项页”栏中,选择“文件组”选项,打开“文件组”设置窗口,可 以对文件组进行设置。关于文件和文件组的设置,可以参考3.3.3节的内容。 设置完成后,单击“确定”按钮,即可创建bookdb数据库,SQL Server不会返回 任何提示信息。可以在“对象资源管理器”窗口的“数据库”文件夹下看到新创建的数据 库。 表示数据文件 可以自动增长 按照百分比增加 按照字节数增加 77 第3章 Chapter 03 数据库和表 图 3.30 “新建数据库”的选项设置窗口 3.3.2 删除数据库 当不再需要数据库或者如果它被移到另一数据库或服务器时,即可删除该数据库。数 据库删除之后,文件及其数据都从服务器上的磁盘中删除。一旦删除数据库,它即被永久 删除,并且不能进行检索,除非使用以前的备份。 删除数据库的操作步骤如下: 打开SQL Server Management Studio窗口,打开“数据库”文件夹。 右击要删除的数据库,然后在弹出的快捷菜单中选择“删除”命令。将会弹出“删 除对象”窗口。 单击“确定”按钮,确认删除。 删除数据库的同时,SQL Server会自动删除存储这个数据库的文件。 注 意 在数据库删除之后应该备份master数据库,因为删除数据库将更新master数据库中的 系统表。如果master需要还原,则从上次备份master之后删除的所有数据库都将仍然在系 统表中有引用,因而可能导致出现错误信息。 3.3.3 数据库文件和文件组设置 文件组允许对文件进行分组,以便于管理和数据的分配及放置。例如,可以分别在3 个磁盘驱动器上创建3个文件(Data1.ndf、Data2.ndf 和 Data3.ndf),并将这3个文件指派到 文件组fgroup1中。然后,可以明确地在文件组fgroup1上创建一个表。对表中数据的查询将 分散到3个磁盘上,因而性能得以提高。在RAID(独立磁盘冗余阵列)条带集上创建单个 文件也可以获得相同的性能改善。然而,文件和文件组使用户得以在新磁盘上轻易地添加 新文件。另外,如果数据库超过单个Microsoft Windows文件的最大大小,则可以使用次要 新概念 SQL Server 2005 教程 78 数据文件允许数据库继续增长。 “文件组”选项卡可以用来创建、删除文件组,并可以设置文件组是否为只读。创建 文件组后,可以将文件放入到文件组中,这可以通过数据库的“文件”选项来完成。 设置文件和文件组的操作步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理 器”窗口中,打开“数据库”文件夹。 右击要更改的数据库,这里以bookdb数据库为例,然后单击 “属性”命令,打开“数据库属性”对话框。 在“选项页”列表框中,单击“文件组”,打开“文件组” 选项设置界面,如图3.31所示。然后输入添加的文件组名称。 图 3.31 创建文件组 在“选择页”列表框中,选择“文件”选项,打开“文件”选项设置界面。单击 底部的“添加”按钮,在“逻辑名称”列中输入新的文件名称,这里输入bookdb01。然后 在“文件组”列中单击下拉列表图标 ,即可选择刚创建的文件组,如图3.32所示。 图 3.32 创建文件并选择文件组 也可以在创建文件的时候,直接创建并设置文件组。单击“文件组”列旁边的下 将不允许修改的表(如历史数 据)置于一些文件组上,然后 将这些文件组标记为只读。这 会防止意外的更新 显示了文件组中包 含的文件数目 单击“添加” 按钮。 输入新的文 件组名称,这里输 入FG02。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\设置文 件和文件组.avi。 79 第3章 Chapter 03 数据库和表 拉箭头,在下拉菜单中单击“<新文件组>”,即可打开“bookdb的新建文件组”对话框, 如图3.33所示。 图 3.33 新建文件组 单击“确定”按钮,即可创建新的文件组,并将要创建的文件添加到该文件组中。 3.3.4 数据库大小估算和收缩数据库 在设置数据库的大小时,应尽量精确估计数据库的大小。如果设置得过小,则设置数 据库自动选项后,会造成数据存放得不连续,导致数据库性能下降。如果设置得过大,则 会造成磁盘空间的浪费。 下面是一个用来估算每个表所需页面数的估算公式: 页数=表的行数/(8080/行的长度) 式中,行的长度就是指表的每一笔记录所占的字节数。例如,某一个表包含两个字段: tt1(整型,16位)、tt2(字符型,长度为5个字节),则该表的行长度为:2+5=7。 为了避免造成数据库中数据的丢失,在更改数据库属性时,要更改数据文件或者日志 文件的大小,SQL Server只允许增大文件的大小,而不允许减小文件的大小。 SQL Server 2000允许收缩数据库中的每个文件以删除未使用的页。数据和事务日志文 件都可以收缩。数据库文件可以作为组或单独地进行手工收缩。数据库也可设置为按给定 的时间间隔自动收缩。该活动在后台进行,并且不影响数据库内的用户活动。 收缩数据库的操作步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理 器”窗口中,打开“数据库”文件夹。 右击要收缩的数据库,依次选择“任务”|“收缩”|“数据 库”命令,打开“收缩数据库”对话框,如图3.34所示。 选择该复选框,可 以将文件组设置为 默认的文件组 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\收缩数 据库.avi。 新概念 SQL Server 2005 教程 80 图 3.34 “收缩数据库”对话框 设置好各种选项后,单击“确定”按钮,即可对选择的文件进行收缩。 如果要收缩个别的数据库文件,可以在步骤 中选择“文件”命令,打开“收缩 文件”对话框,如图3.35所示。 图 3.35 “收缩文件”对话框 设置好各种选项后,单击“确定”按钮,即可对选择的文件进行收缩。 注 意 不能将整个数据库收缩到比其原始大小还要小,也不能将数据库的大小收缩到小于 model数据库的大小。因此,如果数据库创建时的大小为10MB,后来增长到100MB,则该 数据库最小能够收缩到10MB(假定已经删除该数据库中所有数据)。 选择该选项可使释 放的文件空间保留 在数据库文件中,并 使包含数据的页移 到数据库文件的起 始位置 收缩后数据库中剩 余的可用空间量。 以“数据库大小” 栏中的“可用空间” 值作为依据 81 第3章 Chapter 03 数据库和表 3.4 表的建立、删除与修改 数据库建立后,接下来就该建立存储数据的表。本节主要介绍使用SQL Server Management Studio来建立表,并对表进行修改和删除。 3.4.1 新建表 使用企业管理器建立一个表的过程是非常简单的,下面的操作是 在bookdb数据库中建立一个book表。具体操作步骤如下: 打开SQL Server Management Studio窗口,打开“数据库”文 件夹。 在打开的bookdb文件夹中“表”选项上面右击鼠标,选择“新 建表”命令,打开表设计窗口。 在“列名”栏中依次输入表的字段名,并设置每个字段的数 据类型和长度等属性。输入完成后的book表如图3.36所示。 图 3.36 创建表 一般说来,每个表都应该包含一个主键。例如,book表的主键应该为book_id字段。 在book_id字段上右击鼠标,然后选择“设置主键”命令,即可将book_id字段设置为主键。 此时,该字段前面会出现一个钥匙图标,如图3.37所示。 图 3.37 设置主键 提 示 如果要将多个字段设置为主键,可按住Ctrl键,单击每个字段前面的按钮来选择多个 字段,然后再依照上述方法设置主键。 book表的 各个字段 单击可选择 数据类型 钥匙图标表示 该字段为主键 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频 \ 第 3 章 \ 新建 表.avi。 新概念 SQL Server 2005 教程 82 表字段设置完成后,单击工具栏上的“保存”按钮 ,打开“选择名称”对话框, 输入book,如图3.38所示。 单击“确定”按钮,即可创建book表。 依照上述步骤,再创建3个表:orderform表、authors表和clients表。表的结构分别 如图3.39、图3.40和图3.41所示。 图 3.38 保存 book 表 图 3.39 orderform 表的结构 图 3.40 authors 表的结构 图 3.41 clients 表的结构 提 示 这些表将在后面的讲解中作为例子使用。 3.4.2 修改表的结构 表结构的修改和查看的操作步骤是相同的,下面给book表中加入 author字段。操作步骤如下: 在SQL Server Management Studio的右侧窗口中,在dbo.book 表上右击鼠标,然后选择“修改”命令。 在打开的表设计窗口中,右击book_name字段,然后选择“插 入列”命令。 在新插入的列中,输入author_id,设置数据类型为int,如图3.42所示。 图 3.42 插入字段 author 提 示 用户也可以修改已有的字段,包括名称和数据类型等。 3.4.3 建立表间的关联 下面建立上述4个表的关联,操作步骤如下: 在SQL Server Management Studio窗口中,打开bookdb数据 新插入的字段 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\修改表 的结构.avi。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第3章\建立表 关联.avi。 83 第3章 Chapter 03 数据库和表 库,选择“数据库关系图”选项,右击鼠标,在弹出的快捷菜单上选择“新建数据库关系 图”命令,打开“添加表”对话框。如图3.43所示。 图 3.43 “添加表”对话框 单击“添加”按钮,然后单击“关闭”按钮。在book表的author_id字段对应的按 钮上按住鼠标左键,并拖曳到authors表上。此时两表之间会产生一条虚线,如图3.44所示。 图 3.44 拖动 book 表的 author_id 字段到 authors 表上 松开鼠标,此时打开“表和列”对话框,如图3.45所示。在此对话框中,选择关 联的主键的表名称和字段名称,以及关联的外键的表名称和字段名称。 图 3.45 “表和列”对话框 单击此处并拖动到 authors表上 输入关系的名称。 关联的主键的表名 称和字段名称。 关联的外键的表 名称和字段名称。 按住Ctrl键,依 次单击选择表,选择 要添加的表。 新概念 SQL Server 2005 教程 84 设置完成后,单击“确定”按钮。在“外键关系”对话框中,设置新建关系的属 性,如图3.46所示。 图 3.46 “外键关系”对话框 单击“确定”按钮,即可建立两个表间的关系,用一个链子式的连接表示。 依照上面步骤,建立其他表间的关系,最终的关系图如图3.47所示。 图 3.47 建立表间的关系 单击工具栏上的“保存”按钮,打开“选择名称”对话框,输入关系图的名称, 如图3.48所示。 单击“确定”按钮,弹出一提示对话框,如图3.49所示。单击“是”按钮,即可 保存建立的关系图。 提 示 如果要删除表之间的关系,可以在表之间的链子式的链 接上右击,在弹出的快捷菜单上,选择“从数据库中删除关系” 命令,在打开的对话框中单击“是”按钮确认删除即可。 在建立关联时,检查现 有数据是否有问题 复制数据时会复制 相关联的数据 在插入和更新操作时,会 同时修改相关联的数据 图 3.48 保存关系图 85 第3章 Chapter 03 数据库和表 图 3.49 提示对话框 3.4.4 删除表 有时需要删除表(如要实现新的设计或释放数据库的空间时)。删除表时,表的结构定 义、数据、全文索引、约束和索引都永久地从数据库中删除,原来存放表及其索引的存储 空间可用来存放其他表。 如果是单个的表,与其他表没有关联,则可以直接删除。操作步骤如下: 在SQL Server Management Studio窗口中,在“数据库”文件夹下,打开相应的数 据库,然后选择“表”选项。 右击要删除的表,然后在弹出的快捷菜单中选择“删除”命令。 此时,会打开“删除对象”窗口,单击“确定”按钮即可删除选择的表。 但是如果要删除的表与其他表存在关联,则在删除表时会出现错误。下面以bookdb数 据库中的authors表为例,来介绍这种情况下删除表时的出错信息。操作步骤如下: 在SQL Server Management Studio中,在“数据库”文件夹下,打开bookdb数据库, 选择“表”选项。 在authors表上右击鼠标,然后在弹出的快捷菜单中选择“删除”命令。 此时,打开“删除对象”窗口,单击“确定”按钮,系统提示删除表失败,如图 3.50所示。出现这种错误的原因就是authors表与其他表间存在关联。如果该表被删除了, 则原先关联到此表的表字段可能会找不到数据,所以SQL Server为了保持数据库中数据的 完整性,不允许删除和其他表有关联的表。 此时,可以通过查看表之间的依赖关系来确定出错的详细原因。单击“显示依 赖关系”按钮,打开“authors依赖关系”对话框,如图3.51所示。在此对话框中,选择“依 赖于‘authors’的对象”选项,则“依赖关系”列表框中会显示依赖于表authors的对象; 如果选择“[authors]依赖的对象”选项,则“依赖关系”列表框中会显示表authors依赖的对 象。 新概念 SQL Server 2005 教程 86 图 3.50 “删除对象”窗口 图 3.51 “authors 依赖关系”对话框 提 示 解决方法之一就是在企业管理器中,按住Ctrl键,然后选择要删除的表及其与之相关 联的表,然后一并删除。 如果一定要删除选择的表,而该表又与其他表相关联。则必须将关联先删除,然 后才可以删除表。在bookdb文件夹下选择“数据库关系图”,然后双击建立的关系图。 此时,会打开关系图窗口,在要删除的关系上右击鼠标,然后选择“从数据库中 删除关系”命令。 单击可显示与 该表相关联的 表及其字段 系统提示消息: 删除失败。单击 可以查看详细 的失败信息 87 第3章 Chapter 03 数据库和表 此时,authors表和book表间的关系会被删除。关闭关系图窗口,在出现的提示对 话框中,单击“是”按钮,保存关系图。并在出现的对话框中,单击“确定”按钮即可。 返回到SQL Server Management Studio,依照删除单个表的方法删除表(这里并不 删除表,只是介绍删除过程)。 提 示 在关系图窗口中,直接在要删除的表上右击鼠标,然后选择“从数据库中删除表” 命令,在打开的提示对话框中,单击“是”按钮。关闭关系图窗口,选择“保存”命令, 也可以删除表。 3.4.5 记录的新增和修改 记录一般是通过Transact-SQL来添加的,但是从SQL Server 7.0开始,记录的添加和修 改可以通过SQL Server Management Studio来进行。但是需要注意的是,如果表之间有关联 性存在,例如,表A的某个字段参考到表B时,则必须先输入表B的记录,然后才能输入表 A与之相关的记录,否则将会出错。 记录的新增和修改与记录的表内容的查看的操作过程是相同的,就是在打开表的内容 窗口后,直接输入新的记录或者进行修改。 3.5 课堂演练 3.5.1 创建boarddb数据库 创建一个用于公告信息系统的boarddb数据库。操作步骤如下: 在SQL Server Management Studio窗口中,打开“对象资 源管理器”,选择“数据库”文件夹,在上面右击鼠标,在弹出 的快捷菜单上选择“新建数据库”命令。 此时,会打开“新建数据库”窗口。在“数据库名称” 文本框中输入新建数据库的名字boarddb。 在“数据库文件”栏中,设置文件的名称、位置及大小。 在“初始大小”一栏中,输入5。 其他保持默认设置,然后单击“确定”按钮,创建数据库。 3.5.2 创建boarddb数据库中的表 在boarddb数据库中,创建users表和board表。操作步骤如下: 打开SQL Server Management Studio窗口,打开“数据库”文件夹。 打开boarddb文件夹,在“表”选项上面右击鼠标,选择“新建表”命令,打开表 设计窗口。 在“列名”栏中依次输入users表的字段名,各字段名称、数据类型以及是否为空 如表所示。 实讲实训 多媒体演示 多媒体演示参见配套 光盘中的\\视频\第3 章\创建boarddb数据 库.avi。 新概念 SQL Server 2005 教程 88 表3.1 users表的结构 字段名称 数据类型 允许空 说明 userID varchar(50) 否 用户名 password varchar(50) 否 用户密码 username varchar(50) 是 用户姓名 sex bit 是 性别 address varchar(50) 是 地址 email varchar(100) 是 Email telephone varchar(50) 是 电话 输入完成后,单击“保存”按钮。在弹出的对话框中输入users。 重复上面的步骤,创建board表,各字段名称、数据类型以及是否为空,如表3.2 所示。 表3.2 board表的结构 字段名称 数据类型 允许空 说明 board_id uniqueidentifier 否 公告编号 board_title varchar(100) 否 公告题目 board_content varchar(50) 是 公告内容 board_time datetime 是 提交时间 board_poster varchar(50) 是 提交用户名 3.6 小结 本章介绍了如何使用SQL Server Management Studio来管理数据库和表,一般来说,数 据库和表结构的建立和修改都是通过SQL Server Management Studio来完成的。 数据库的物理存储对象是页和区,这两个概念可以用来估算数据库所占用的空间,因 此作为一个数据库管理员,了解这方面的知识还是很有必要的。 创建一个数据库,仅仅是创建了一个空壳,它是以model数据库为模板创建的,因此其 初始大小不会小于model数据库的大小。 在创建数据库时,同时会创建事务日志。事务日志是在一个文件上预留的存储空间, 在修改写入数据库之前,事务日志会自动记录对数据库对象所做的所有修改。 表结构的设计和修改都比较简单,和其查看操作过程是类似的。表的删除操作也很简 单,但是要注意的是,如果与其他表存在关联时,则不能直接删除表。要先删除关联,然 后再删除表。 89 第3章 Chapter 03 数据库和表 3.7 课后练习 3.7.1 选择题和简答题 (1)作为一个数据库管理员,要创建一个新的数据库,该数据库中只包含一个表,不 包含其他任何数据库对象。该表中每一笔记录的长度为1024B,如果表中包含100 000条记 录,则应创建多大的数据库才能满足要求? A. 120MB B. 200MB C. 50MB D.75MB (2)如果在创建新的数据库时,发现可以设置的最小容量为5MB,而不是通常情况下 的1MB,最可能的原因是: A. master数据库的大小为5MB B. 缺省数据文件的大小为5MB C. 应该使用Transact-SQL而不是企业管理器来创建数据库 D. model数据库的大小为5MB (3)假定要创建一个大于25GB的数据库,不幸的是,服务器只有3个20GB的硬盘。 这种情况下,应该怎么办? A. 购买一个大于25GB的硬盘 B. 在空硬盘上创建多个数据文件,再创建一个存储在多个数据文件上的数据库 C. 在空硬盘上创建多个数据文件,再在每个数据文件上创建多个数据库,然后将这些 较小的数据库连接为一个较大的数据库 D. 使用NTFS分区,然后进行压缩 (4)在检查SQL Server的设置情况时,突然发现某一数据库的大小为250MB,但是却 只使用了20%的空间。假定该数据库容量不会再增大,则应该采取什么操作? A. 为了节省空间,应该减小数据文件的大小 B. 为了节省空间,应该进行磁盘碎片整理 C. 为了节省空间,应该收缩数据库 D. 为了节省空间,应该使用NTFS分区,然后使用压缩功能进行压缩 (5)数据库的存储结构分为哪两种?其含义分别是什么? (6)事务日志文件的作用是什么? (7)简单介绍删除与其他表存在关联的表的操作步骤。 3.7.2 操作题 (1)在SQL Server Management Studio创建一个名称为Resource的数据库。 (2)创建一个名为Staff的表,包含staff_id、name、sex、age、degree等字段。 (3)在Staff表中输入几条记录。 第 4 章 账户和存取权限 04 Chapter 本章导读: ” SQL Server的验证模式 ” 验证模式的设置 ” Windows身份验证模式对SQL Server的影响 ” 登录账户的设置 ” 用户的创建 ” 用户的权限设置 ” 角色的创建 ” 角色的权限设置 4.1 SQL Server的验证模式 在第2章中,简单介绍了验证模式的概念,本节将进行详细的介绍。为了实现安全性, SQL Server对用户的访问进行两个阶段的检验: y 验证阶段(Authentication) 用户在SQL Server上获得对任何数据库的访问权限之 前,必须登录到SQL Server上,并且被认为是合法的。SQL Server或者Windows对 用户进行验证。如果验证通过,用户就可以连接到SQL Server上;否则,服务器将 拒绝用户登录。从而保证了系统安全。 y 许可确认阶段(Permission Validation) 用户验证通过后,登录到SQL Server上, 系统检查用户是否有访问服务器上数据的权限。 在验证阶段,系统是对用户登录进行验证。SQL Server和Windows是结合在一起的,因 此就产生了两种验证模式:Windows身份验证模式和混合模式(Windows身份验证和SQL Server身份验证)。 SQL Server 2005 Database Engine管理者可以通过权限进行保护的实体的分层集合。这 些实体称为“安全对象”。在安全对象中,最突出的是服务器和数据库,但可以在更细的级 别上设置离散权限。SQL Server通过验证主体是否已获得适当的权限来控制主体对安全对 象执行的操作。 4.1.1 Windows验证模式 在Windows验证模式下,SQL Server检测当前使用Windows的用户账户,并在系统注册 表中查找该用户,以确定该用户账户是否有权限登录。在这种方式下,用户不必提交登录 91 第4章 Chapter 04 账户和存取权限 名和密码让SQL Server验证。 Windows验证模式有以下主要优点: y 数据库管理员的工作可以集中在管理数据库上面,而不是管理用户账户。对用户 账户的管理可以交给Windows去完成。 y Windows有着更强的用户账户管理工具。可以设置账户锁定、密码期限等。如果不 是通过定制来扩展SQL Server,SQL Server是不具备这些功能的。 y Windows的组策略支持多个用户同时被授权访问SQL Server。 实际上,SQL Server是从RPC协议连接中自动获取登录过程中的Windows用户账户信息 的。多协议和命名管道自动使用RPC协议。因此,在客户和服务器间,使用上述网络库可 以使用Windows验证模式。 但是,应该注意的是,要使用多协议或者命名管道在客户和服务器将建立连接,必须 满足以下两个条件中的一个: y 客户端的用户必须有合法的服务器上的Windows账户,服务器能够在自己的域中或 者信任域中验证该用户。 y 服务器启动了Guest账户,但是该方法会带来安全上的隐患,因而不是一个好的方 法。 注 意 在本书中,如果不特殊说明,Windows指的是Windows NT/2000/2003。另外,关于域 和信任域、组策略,以及Windows的用户账户管理等概念,可参考Windows的帮助和使用 手册。 4.1.2 混合验证模式 混合验证模式允许以SQL Server验证模式或者Windows验证模式来进行验证。使用哪个 模式取决于在最初的通信时使用的网络库。如果一个用户使用的是TCP/IP Sockets进行登录 验证,则将使用SQL Server验证模式;如果用户使用命名管道,则登录时将使用Windows 验证模式。这种模式能更好地适应用户的各种环境。但是对于Windows 9x系列的操作系统, 只能使用SQL Server验证模式。 SQL Server验证模式处理登录的过程为:用户在输入登录名和密码后,SQL Server在系 统注册表中检测输入的登录名和密码。如果输入的登录名存在,而且密码也正确,就可以 登录到SQL Server上。 提 示 验证模式的选用通常与网络验证的模型和客户与服务器间的通信协议有关。如果网 络主要是Windows网,则用户登录Windows时已经得到了确认,因此,使用Windows验证 模式将减轻系统的工作负担。但是,如果网络主要是Novell网络或者对等网,则使用SPX 协议和SQL Server验证模式将是很方便的。因为,这种情况下,只需创建SQL Server登录 账户,而不用创建Windows账户。 新概念 SQL Server 2005 教程 92 混合验证模式具有如下优点: y 创建了Windows之上的另外一个安全层次。 y 支持更大范围的用户,例如非Windows客户、Novell网络等。 y 一个应用程序可以使用单个的SQL Server登录和口令。 4.1.3 设置验证模式 在第一次安装SQL Server,或者使用SQL Server连接其他服务器的时候,需要指定验证 模式。对于已经指定验证模式的SQL Server服务器,在SQL Server中还可以进行修改。操作 步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理器”窗口中,选择服 务器,然后右击鼠标,在弹出的快捷菜单上选择“属性”命令,然后在打开的“服务器属 性”对话框中,选择“安全性”选项,打开“安全性”选项卡,如图4.1所示。 图 4.1 “服务器属性”对话框 在“服务器身份验证”栏中设置验证模式后,单击“确定”按钮,打开提示对话 框,提示重新启动SQL Server,才能使新的设置生效,如图4.2所示。 图 4.2 提示对话框 单击“确定”按钮,然后重新启动SQL Server,以新的验证模式登录服务器。 93 第4章 Chapter 04 账户和存取权限 4.2 账户和角色 在SQL Server中,账户有两种,一种是登录服务器的登录账户(login name),另外一 种是使用数据库的用户账户(user name)。登录账户只是让用户登录到SQL Server中,登 录名本身并不能让用户访问服务器中的数据库。要访问特定的数据库,还必须具有用户名。 用户名在特定的数据库内创建,并关联一个登录名(当一个用户创建时,必须关联一 个登录名)。用户定义的信息存放在服务器上的每个数据库的sysusers表中,用户没有密码 同它相关联。通过授权给用户来指定用户可以访问的数据库对象的权限。 提 示 可以这样想象,假设SQL Server是一个包含许多房间的大楼,每一个房间代表一个数 据库,房间里的资料可以表示数据库对象。则登录名就相当于进入大楼的钥匙,而每个房 间的钥匙就是用户名。房间中的资料是根据用户名的不同而有不同的权限的。 4.2.1 服务器的登录账户 要登录到SQL Server,必须具有一个登录账户。创建一个登录账 户的操作步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理 器”窗口中,打开服务器,然后在“安全性”下面的“登录名”上右 击鼠标,在打开的快捷菜单中选择“新建登录名”命令,如图4.3所 示。 图 4.3 “新建登录名”命令 其中两个默认登录账户的含义如下: y BUILTIN\Administrators 凡是属于Windows中Administrators组的账户都允许登录 SQL Server。 系统创建的默 认登录账户 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第4章\创建登 录账户.avi。 新概念 SQL Server 2005 教程 94 y sa 超级管理员账户,允许SQL Server的系统管理员登录,此SQL Server的管理员 不一定是Windows的管理员。 此时,打开“登录名-新建”窗口,如图4.4所示。 图 4.4 “登录名-新建”窗口 在“选择页”列表中,选择“服务器角色”选项,打开“服务器角色”选项卡, 如图4.5所示。在此选项卡中,可以设置登录账户所属的服务器角色。 图 4.5 “服务器角色”选项卡 角色是一组用户所构成的组,可分为服务器角色和数据库角色。下面介绍服务器角色, 选择登录账户所属 的服务器角色。 设置密码。 选择默认数据库。 输入登录名。 95 第4章 Chapter 04 账户和存取权限 数据库角色在后面的章节中将进行介绍。 服务器角色是负责管理和维护SQL Server的组,一般只会指定需要管理服务器的登录 者属于服务器角色。SQL Server 2005在安装过程中定义几个固定的服务器角色,其具体权 限如下: y sysadmin 全称为System Administrators,可以在 SQL Server中执行任何活动。 y serveradmin 全称为Server Administrators,可以设置服务器范围的配置选项,关闭 服务器。 y setupadmin 全称为Setup Administrators,可以管理链接服务器和启动过程。 y securityadmin 全称为Security Administrators,可以管理登录和创建数据库的权限, 还可以读取错误日志和更改密码。 y processadmin 全称为Process Administrators,可以管理在SQL Server中运行的进 程。 y dbcreator 全称为Database Creators,可以创建、更改和删除数据库。 y diskadmin 全称为Disk Adminstrators,可以管理磁盘文件。 y bulkadmin 全称为Bulk Insert Adminstrators,可以执行BULK INSERT(大容量插 入)语句。 y public public角色具有查看任何数据库的权限。 提 示 属于Windows Adminstrators组的账户,在SQL Server 2005中被自动设置为sysadmin服 务器角色。 在“选项页”列表中,选择“用户映射”选项,打开“用户映射”选项卡。单击 选择bookdb数据库前面的复选框。此时,用户列出现bookadm用户,表示该登录账户允许 bookadm用户访问bookdb数据库,如图4.6所示。 图 4.6 “用户映射”选项卡 设置完成后,单击“确定”按钮即可创建一个名称为bookadm的登录账户,同时 新概念 SQL Server 2005 教程 96 在bookdb数据库中自动创建了一个用户bookadm。 在图4.4中,如果选择“Windows身份验证”单选按钮,则“登录名”文本框后面 的“搜索”按钮被激活,单击可打开“选择用户或组”对话框,如图4.7所示。可以从该对 话框中输入Windows系统的用户作为登录账户。 图 4.7 选择 Windows 系统的用户作为登录账户 如果要修改登录账户的属性,可在登录账户上面右击鼠标,然后在弹出的快捷菜单中 选择“属性”命令,即可打开登录账户的属性对话框,它也包含上面创建过程中的3个选项 卡,各项含义与上面相同。 如果要删除一个登录账户,在右击登录账户弹出的快捷菜单中选择“删除”命令,此 时会打开一个提示对话框,单击“是”按钮确定删除。 提 示 在第9章中,将看到使用SQL Server提供的存储过程也可以添加、修改和删除登录账 户。对于下面的用户、角色,SQL Server同样提供了存储过程来进行添加、修改和删除操 作。 4.2.2 数据库用户 每个登录账户在一个数据库中只能有一个用户账户,但是每个登录账户可以在不同的 数据库中各有一个用户账户。如果在新建登录账户的过程中,指定对某个数据库具有存取 权限,则在图4.6所示的“用户映射”选项卡中,可以通过映射用户来创建一个与该登录账 户同名的用户账户。例如,上面新建的bookadm登录账户,通过映射用户自动创建了一个 用户bookadm,具有对bookdb数据库访问的权限(见图4.6)。 如果在创建登录账户时没有指定对某个数据库的存取权限,则在 该数据库中,创建一个新的用户账户,并关联到该登录账户,则该登 录账户会自动具有对该数据库的访问权限。下面在AdventureWorks数 据库中创建一个用户账户bookA,并将其关联到bookadm登录账户中。 操作步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理 器”窗口中,打开服务器,打开AdventureWorks数据库,然后打开“安 全性”窗口。在“用户”上右击鼠标,在弹出的快捷菜单中,选择“新建用户”命令,打 开“数据库用户-新建”窗口,如图4.8所示。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第4章\创建数 据库用户.avi。 输入用户名。 97 第4章 Chapter 04 账户和存取权限 图 4.8 “数据库用户-新建”窗口 注 意 登录账户具有对某个数据库的访问权限,并不表示该登录账户对该数据库具有存取 的权限。如果要对数据库中的对象进行插入及更新等操作,还需要设置用户账户的权限。 单击“登录名”文本框右端的按钮 ,打开“选择登录名”对话框,单击“浏览” 按钮,打开“查找对象”对话框,选择bookadm登录账户,如图4.9所示。 图 4.9 “查找对象”对话框 单击“确定”按钮,返回到“选择登录名”对话框,如图4.10所示。 新概念 SQL Server 2005 教程 98 图 4.10 “选择登录名”对话框 单击“确定”按钮,返回到“数据库用户-新建”窗口。如果此时单击“确定”按 钮,即可创建一个新用户。但是没有为该用户指定任何权限。要为该用户指定权限,可在 “选项页”列表中选择“安全对象”选项,打开“安全对象”选项卡,如图4.11所示。 图 4.11 “安全对象”选项卡 单击“添加”按钮,打开“添加对象”对话框,如图4.12所示。在此对话框中, 可以选择特定的对象,例如,表、视图或存储过程等;也可以选择特定类型的所有对象, 例如所有表;也可以选择属于某一架构的所有对象,例如Production架构。 99 第4章 Chapter 04 账户和存取权限 图 4.12 “添加对象”对话框 这里选择Production架构的所有对象。在“架构名称”下拉列表框中选择Production 架构,然后单击“确定”按钮,返回到“数据库用户-新建”窗口。 在“安全对象”栏中选择要设置用户权限的对象,例如Product表。然后在下面的 权限设置栏中设置用户对Product表的权限,如图4.13所示。可以将各类权限设置为“授予”、 “具有授予权限”、“允许”或“拒绝”,或者不进行任何设置。选中“拒绝”将覆盖其 他所有设置。 图 4.13 设置用户权限 权限则包括以下几种: y Alter 授予更改特定安全对象的属性(所有权除外)的权限。当授予对某个范围 的Alter权限时,也授予更改、创建或删除该范围内包含的任何安全对象的权限。 例如,对架构的Alter权限包括在该架构中创建、更改和删除对象的权限。 数据库的对象 新概念 SQL Server 2005 教程 100 y Control 为被授权者授予类似所有权的功能。被授权者实际上对安全对象具有所 定义的所有权限。 y Delete 删除表或视图中的数据。 y Insert 在表或视图中插入记录。 y References 对表或视图进行引用。 y Select 对表或视图的查询。 y Take ownership 允许被授权者获取所授予的安全对象的所有权。 y Update 对表或视图中的数据进行修改。 y View definition 允许被授权者访问元数据。 如果要设置对表或视图的某一字段进行操作的权限,可在列表中选择表或视图, 然后单击“列权限”按钮,可打开“列权限”对话框。使用该对话框即可进行相应权限的 设置。 设置完成后,单击“确定”按钮,即可创建数据库用户并设置相应的权限。 提 示 前面介绍的是用户账户的创建和权限设置,如果要删除一个用户账户,则只要从“用 户”文件夹中选择要删除的用户,然后按Delete键或右击鼠标并执行“删除”命令即可。 4.2.3 角色 和登录账户类似,用户账户也可以分成组,称为数据库角色(Database Roles)。数据 库角色应用于单个数据库,它包括一列Windows用户账户和组。当最终用户通过客户应用 程序连接到分析服务器时,数据库角色中的规范即应用于他们对分析服务器上对象的访问。 数据库角色不是用来授权或拒绝对于对象的管理访问。 角色是一个强大的工具,可以将用户集中到一个单元中,然后对该单元应用权限。对 一个角色授予、拒绝或废除的权限也适用于该角色的任何成员。可以建立一个角色来代表 单位中一类工作人员所执行的工作,然后给这个角色授予适当的权限。当工作人员开始工 作时,只需将他们添加为该角色成员,当他们离开工作时,将他们从该角色中删除。而不 必在每个人接受或离开工作时,反复授予、拒绝和废除其权限。权限在用户成为角色成员 时自动生效。 在SQL Server中,数据库角色可分为两种: y 服务器角色 由服务器账户组成的组,负责管理和维护SQL Server组。详细内容可 以参考前面4.2.1节。 y 数据库角色 由数据库成员所组成的组,此成员可以是用户或者其他的数据库角 色。 y 应用程序角色 用来控制应用程序存取数据库,本身并不包含任何成员。 以下将介绍数据库角色、应用程序角色以及public数据库角色的权限。 101 第4章 Chapter 04 账户和存取权限 1. 数据库角色 在数据库创建时,系统默认创建了10个固定的数据库角色。打开bookdb数据库,然后 依次选择“安全性”|“角色”|“数据库角色”选项,即可看到默认的数据库角色,如图4.14 所示。 图 4.14 默认的 10 个数据库角色 public角色是最基本的数据库角色。其余9个默认数据库角色的含义如下: y db_owner 在数据库中有全部权限。 y db_accessadmin 可以添加或删除用户ID。 y db_securityadmin 可以管理全部权限、对象所有权、角色和角色成员资格。 y db_ddladmin 可以发出ALL DDL,但不能发出GRANT(授权)、REVOKE或DENY 语句。 y db_backupoperator 可以发出DBCC、CHECKPOINT和BACKUP语句。 y db_datareader 可以选择数据库内任何用户表中的所有数据。 y db_datawriter 可以更改数据库内任何用户表中的所有数据。 y db_denydatareader 不能选择数据库内任何用户表中的任何数据。 y db_denydatawriter 不能更改数据库内任何用户表中的任何数据。 可以查看角色的属性,也可以将一个用户添加到角色中。下面以 db_owner数据库角色为例,来查看它的属性,并将用户bookadm加入 到该角色中。操作步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理 器”窗口的数据库bookdb文件夹下,依次选择“安全性”|“用户”| “角色”|“数据库角色”选项。 在db_owner角色上右击鼠标,然后选择“属性”命令,打开 “数据库角色属性-db_owner”窗口,如图4.15所示。 默认的10个数 据库角色 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第4章\将用户 加入角色.avi。 新概念 SQL Server 2005 教程 102 图 4.15 “数据库角色属性-db_owner”对话框 要将用户bookadm加入到该角色中,可单击“添加”按钮,打开“选择数据库用 户或角色”对话框,直接输入对象名称或单击“浏览”按钮进行选择,设置完成后单击“确 定”按钮,返回到“选择数据库用户或角色”对话框,如图4.16所示。 图 4.16 “选择数据库用户或角色”对话框 单击“确定”按钮,即可将用户bookadm加入到db_owner数据库角色中。 也可以创建一个新的角色。建立一个数据库角色的操作步骤如下: 打开账户,在“对象资源管理器”窗口中,在数据库bookdb文件夹下,依次选择 “安全性”|“角色”选项。 右击“数据库角色”选项,在弹出的快捷菜单中选择“新建数据库角色”命令, 打开“数据库角色-新建”窗口,如图4.17所示。 单击该按钮可为该 角色加入一个用户 默认每个数据库的db_owner中一 定包括dbo用户,dbo是默认存在的 用户,是指数据库的创建者 单击该按钮可 删除选中的用 户,但是dbo是 不能被删除的 103 第4章 Chapter 04 账户和存取权限 图 4.17 “数据库角色—新建”对话框 在“选项页”列表中,选择“安全对象”选项,打开“安全对象”选项卡。在该 选项卡中,可以设置角色的权限。操作步骤和设置用户权限的操作步骤相同,详细步骤可 以参考4.2.2节。 设置完成后,单击“确定”按钮即可创建新的数据库角色。 2. 应用程序角色 SQL Server中的安全系统在最低级别,即数据库本身上实现。无论使用什么应用程序 与SQL Server通信,这都是控制用户活动的最佳方法。但是,有时必须自定义安全控制以 适应个别应用程序的特殊需要,尤其是当处理复杂数据库和含有大表的数据库时。 此外,可能希望限制用户只能通过特定应用程序(例如使用SQL查询分析器或Microsoft Excel)来访问数据或防止用户直接访问数据。限制用户的这种访问方式将禁止用户使用应 用程序(如SQL查询分析器)连接到SQL Server实例并执行编写质量差的查询,以免对整个 服务器的性能造成负面影响。 SQL Server使用应用程序角色来满足这些要求,应用程序角色和数据库角色的区别有 以下3点: y 应用程序角色不包含成员。不能将Windows组、用户和角色添加到应用程序角色; 当通过特定的应用程序为用户连接激活应用程序角色时,将获得该应用程序角色 的权限。用户之所以与应用程序角色关联,是由于用户能够运行激活该角色的应 用程序,而不是因为它是角色成员。 y 默认情况下,应用程序角色是非活动的,需要用密码激活。 y 应用程序角色不使用标准权限。当一个应用程序角色被该应用程序激活以用于连 接时,连接会在连接期间永久地失去数据库中所有用来登录的权限、用户账户、 其他组或数据库角色。连接获得与数据库的应用程序角色相关联的权限,应用程 单击选择所有 者。 输入角色名称。 单击可为该角 色添加用户成员。 新概念 SQL Server 2005 教程 104 序角色存在于该数据库中。因为应用程序角色只能应用于它们所存在的数据库中, 所以连接只能通过授予其他数据库中guest用户账户的权限,获得对另一个数据库 的访问。因此,如果数据库中没有guest用户账户,则连接无法获得对该数据库的 访问。如果guest用户账户确实存在于数据库中,但是访问对象的权限没有显式地 授予guest,则无论是谁创建了对象,连接都不能访问该对象。用户从应用程序角 色中获得的权限一直有效,直到连接从SQL Server退出为止。 若要确保可以执行应用程序的所有函数,连接必须在连接期间失去应用于登录和用户 账户或所有数据库中的其他组或数据库角色的默认权限,并获得与应用程序角色相关联的 权限。例如,如果应用程序必须访问通常拒绝用户访问的表,则应废除对该用户拒绝的访 问权限,以使用户能够成功使用该应用程序。应用程序角色通过临时挂起用户的默认权限 并只对它们指派应用程序角色的权限而克服任何与用户的默认权限发生的冲突。 下面是一个使用应用程序角色的例子: 假设用户Sue运行销售应用程序。该应用程序要求在数据库Sales中的表Products和 Orders上有SELECT、UPDATE和INSERT权限,但Sue在使用SQL查询分析器或任何其他工 具访问Products或Orders表时不应有SELECT、INSERT或UPDATE权限。若要确保如此,可 以创建一个拒绝Products和Orders表上的SELECT、INSERT或UPDATE权限的用户-数据库 角色,然后将Sue添加为该数据库角色的成员。接着在Sales数据库中创建带有Products和 Orders表上的SELECT、INSERT和UPDATE权限的应用程序角色。当应用程序运行时,指 应用程序通过使用sp_setapprole存储过程提供密码激活应用程序,并获得访问Products和 Orders表的权限。如果Sue尝试使用除该应用程序外的任何其他工具登录到SQL Server实例, 则将无法访问Products或Orders表。 创建应用程序角色的操作步骤和创建标准角色的步骤类似,只是在创建过程中要设置 应用程序角色的密码。如果要删除角色,则可以直接选取角色,然后按Delete键或者右击鼠 标选择“删除”命令。 3. public 数据库角色的权限 public数据库角色是每个数据库最基本的数据库角色,每个用户可以不属于其他9个固 定数据库角色,但是至少会属于public数据库角色。当在数据库中添加新用户账户时,SQL Server会自动将新用户账户加入public数据库角色中。 双击public角色可以打开其属性对话框,可查看它的属性和权限。但是对于用户建立的 数据库对象,例如用户建立的表,public角色默认是不设置权限。 4.2.4 用户和角色的权限问题 用户是否具有对数据库存取的权利,要看其权限设置而定,但是,它还要受其所属角 色的权限的限制。 1. 用户权限继承角色的权限 数据库角色中可以包含许多用户,用户对数据库对象的存取权限也继承自该角色。假 105 第4章 Chapter 04 账户和存取权限 设用户User1属于角色Role1,角色Role1已经取得对表table1的SELECT权限,则用户User1 也自动取得对表table1的SELECT权限。如果Role1对table1没有INSERT权限,而User1取得 了对表table1的INSERT权限,则User1最终也取得对表table1的INSERT权限。允许的权限继 承关系如表4.1所示。 表4.1 允许的权限继承 table1 SELECT INSERT public的权限 没有设置 没有设置 Role1的权限 √ 没有设置 User1的权限 没有设置 √ User1的最终权限 √ √ 提 示 表中“√”符号表示取得该权限,“×”符号表示拒绝该权限。 而拒绝的权限是优先的,只要Role1和User1中的之一拒绝,则该权限就是拒绝的。拒 绝的权限继承如表4.2所示。 表4.2 拒绝的权限继承 table1 SELECT INSERT public的权限 没有设置 没有设置 Role1的权限 √ × User1的权限 × √ User1的最终权限 × × 2. 用户分属不同角色 如果一个用户分属于不同的数据库角色,例如,用户User1既属于角色Role1,又属于 角色Role2,则用户User1的权限基本上是以Role1和Role2的并集为准。但是只要有一个拒绝, 则用户User1的权限就是拒绝。 4.3 课堂演练 4.3.1 创建登录账户boardacc 在boarddb数据库中创建一个登录账户boardacc,默认登录数据库为boarddb,并关联一 个数据库用户boardacc。操作步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理器”窗口中,打开服 务器,然后在“安全性”下面的“登录名”上右击鼠标,在打开的快捷菜单中单击“新建 登录名”命令。 新概念 SQL Server 2005 教程 106 此时,打开“登录名-新建”窗口,进行如下设置: y 在“登录名”文本框中输入boardacc。 y 选择“SQL Server身份验证”单选按钮,并输入密码。 y 取消“强制密码过期”和“用户在下次登录时必须更改密码”两个复选框。 y 在“默认数据库”下拉列表框中选择boarddb数据库。 在“选择页”列表中,选择“服务器角色”选项,打开“服务器角色”选项卡。 在“服务器”列表框中选择sysadmin角色。 在“选项页”列表中,选择“用户映射”选项,打开“用户映射”选项卡。选择 boarddb数据库前面的复选框。此时,用户列出现boardacc用户,表示该登录账户允许boardacc 用户访问boarddb数据库。 设置完成后,单击“确定”按钮即可创建一个名称为boardacc的登录账户,同时在 boarddb数据库中自动创建了一个用户boardacc。 4.3.2 设置boardacc用户的权限 在创建boardacc登录账户后,同时创建了一个boarddb数据库的boardacc用户,下面对该 用户设置SECLECT、INSERT和UPDATE权限。操作步骤如下: 打开SQL Server Management Studio窗口,在“对象资源管理器”窗口中,打开服 务器,打开boarddb数据库,选择“安全性”|“用户”选项,在boardacc上右击鼠标,在打 开的快捷菜单中选择“属性”命令。 在boardacc用户的属性窗口中的“选择页”列表中选择“安全对象”选项,可依照 4.2.2节的操作设置其SECLECT、INSERT和UPDATE权限。 4.4 小结 本章介绍了SQL Server的验证模式、登录账户、用户和角色。对用户和角色的权限设 置也做了详细的介绍。 SQL Server支持两种验证模式:Windows验证模式和混合验证模式。Windows验证模式 是使用Windows的验证机制;混合验证模式则是使用Windows和SQL Server验证两种方法的 结合。Windows验证模式适用于Windows组,它适用于命名管道的RPC网络库。混合验证模 式适用于所有的网络库。 登录名被放置在master数据库中,用来对用户进行验证。用户名被关联在数据库中, 用来将登录名连接到特定的数据库中。每一个登录名在一个数据库中只能关联到一个用户 上。如果一个有登录名的用户试图访问一个没有与该用户对应的用户账户的数据库时,将 使用guest的用户对数据库进行访问。 用户名的信息被存储在每个数据库中的系统表中。用户名的信息包括所有组的信息。 登录名的信息被存放在master数据库的syslogins表中。 可以对表和视图授予查询、插入、修改和删除的权限,但是对存储过程只能授予执行 的权限。 107 第4章 Chapter 04 账户和存取权限 角色是用户组成的集合,角色和用户的权限决定了用户的最终权限。而拒绝的权限是 优先的。这有助于数据库的安全。 4.5 课后练习 4.5.1 选择题和简答题 (1)如果所有需要访问SQL Server的用户都有Windows的账户,而且SQL Server安装 在和用户账户域相同域的一个服务器上。假设所有的用户都使用TCP/IP和服务器连接。这 种情况下应该使用哪种安全模式? A. 混合安全模式 B. Windows验证模式 C. 同时使用NT验证模式和混合验证模式 (2)如果将服务器配置为Windows验证模式,但是不能使用Windows登录名访问服务 器。导致这种情况最可能的原因是什么? A. 没有重新启动SQL Server服务 B. 没有重新启动管理所有安全请求的SQLServerAgen服务 C. 没有为任何用户授予对服务器进行管理的访问权 D. 没有使用企业管理器对Windows账户的登录名进行映射 (3)如果要让Windows 和UNIX的用户能够同时访问SQL Server,并且在管理用户上 要尽可能省事,则应选择哪种验证模式? A. 混合安全模式 B. Windows验证模式 C. 同时使用NT验证模式和混合验证模式 (4)验证模式的信息保存在哪里? A. 在注册表中 B. 在master数据库的sysconfigures表中 C. 在事务日志中 D. 在master数据库的syslogins表中 (5)如果要为所有的登录名提供有限的数据访问,则哪种方法最好? A. 在数据库中增加guest用户,并为它授予适当的权限 B. 为每个登录名增加一个用户,并为用户设置权限 C. 为每个登录名增加一个用户,然后将用户增加到一个组中,为这个组授予权限 D. 为每个登录名增加权限 (6)哪个数据库拥有sysusers表? A. 所有数据库 B. 所有用户创建的数据库 新概念 SQL Server 2005 教程 108 C. master数据库 D. 该表保存在注册表中 (7)简单叙述应用程序角色的主要作用。 4.5.2 操作题 (1)创建一个登录账户manager,将其设置为Windows验证模式,并将其管理到第3章 中创建的Staff数据库中。 操作步骤提示: 因为是Windows验证模式,因此需要首先创建一个Windows账户。通过“控制面板” 中的“用户账户”创建一个tbook用户。 依照4.2.2节中的操作创建一个登录账户,并将其关联到bookdb数据库中,其关联 用户名采取默认值tbook。 (2)设置Staff数据库中manager用户的权限。 第 5 章 Transact-SQL 及其程 序设计基础 05 Chapter 本章导读: ” SQL语言简介 ” 简单数据查询 ” 查询指定的列 ” 查询结果排序 ” 多表查询 ” 数据插入和删除 ” 数据库操作 ” Transact-SQL程序设计基础 5.1 SQL语言 SQL的全称为Structured Query Language(结构化查询语言),它利用一些简单的句子 构成基本的语法,来存取数据库的内容。由于SQL简单易学,目前它已经成为关系数据库 系统中使用最广泛的语言。 SQL是在20世纪70年代末由IBM公司开发出来的一套程序语言,并被用在DB2关系数 据库系统中。但是,直到1981年,IBM推出商用的SQL/DS关系型数据库系统,Oracle及其 他大型关系型数据库系统相继出现,SQL才得以广泛应用。 5.1.1 概述 由于在产业界有多种关系型数据库系统,因此各家公司都可能有自己的SQL语法或者 可以定义不同的数据类型。例如,Sybase与Microsoft公司使用Transact-SQL,而Oracle公司 使用PL/SQL(Procedural Language extension to SQL),将原来非过程性的SQL语法改变为 过程性语法。 基于上面的原因,使得SQL有ANSI(American National Standards Institute,美国国家标 准局)SQL-92标准与产业界的标准之分。ANSI SQL-92标准定义了SQL关键字与语法的标 准,而各公司在其基础上又增加了各自的扩充。因此,虽然各公司的数据库系统使用的SQL 不尽相同,但是基本语法以及关键字等还是相互兼容的。 SQL不尽相同,但是基本语法以及关键字等还是相互兼容的。 新概念 SQL Server 2005 教程 110 提 示 Transact-SQL是SQL Server使用的SQL语言,它也在ANSI SQL-92标准的基础上进行 了扩充,使得其功能更为强大,使用更为方便。 SQL语言是应用于数据库的语言,本身是不能独立存在的。它是一种非过程性 (non-procedural)语言,与一般的高级语言,例如C/C++、Pascal,是大不相同的。一般的 高级语言在存取数据库时,需要依照每一行程序的顺序处理许多的动作。但是使用SQL时, 只需告诉数据库需要什么数据,怎么显示就可以了。具体的内部操作则由数据库系统来完 成。 例如,要从bookdb数据库中的book表中查找书名为《Windows 2003 Server网络管理》 的书,使用简单的几行命令即可(实际上,该语句经常写为一行,这里只是为了说明,将 其分成了3行),如图5.1所示。 图 5.1 从 book 表中查找书名为《Windows 2003 Server 网络管理》的书 5.1.2 SQL语言的分类 SQL语言按照用途可以分为如下3类: y DDL(Data Definition Language) 数据定义语言。 y DML(Data Manipulation Language) 数据处理语言。 y DCL(Data Control Language) 数据控制语言。 下面分别介绍这3类。 1. 数据定义语言 在数据库系统中,每一个数据库、数据库中的表、视图和索引等都是对象。要建立一 个对象,都可以通过SQL语言来完成。类似于这一类定义数据库对象的SQL叙述即为DDL 语言。例如,数据库和表的创建。 2. 数据处理语言 SQL语法中处理数据的叙述称为DML。例如,使用SELECT查询表中的内容,或者使 用INSERT(插入)、DELETE(删除)和UPDATE(更新)一笔记录等。这些属于DML。 注 意 具体的DDL、DML语言的SQL语言操作,例如表的建立,查询表中的数据等,均可 参考下面的介绍。 指定表名称,这里从 表book中获取数据 ' Windows 2003Server 网络管理 ' 选择表中的字段,*表 示选择所有字段 指定查询的条件,这 里是指定书名 111 第5章 Chapter 05 Transact-SQL及其程序设计基础 3. 数据控制语言 对单个的SQL语句来说,不管执行成功或者失败,都不会影响到其他的SQL语句。但 是在某些情况下,可能需要一次处理好几个SQL语句,而且希望它们必须全部执行成功, 如果其中一个执行失败,则这一批SQL语句都不要执行。已经执行的应该恢复到开始的状 态。 举个简单的银行转账的例子。假设要从A账户中转10 000元到B账户中,首先从A账户 中扣除10 000元,然后在B账户中加入10 000元。但是,如果从A账户中扣除10000元后,出 现错误,导致下一步在B账户中加入10 000元的操作不能完成,则A账户白白被扣除了10000 元。因此,应保证这些操作要么一起完成,要么都不要执行。这种方式在SQL中称做事务 (Transaction)。 在SQL中,可以使用DCL将数个SQL语句组合起来,然后交给数据库系统一并处理。 详细内容见7.4节。 5.2 Transact-SQL基础 SQL Server提供了多种图形和命令行工具,用户可以使用不同的方法来访问数据库。 但是这些工具的核心却是Transact-SQL语言。SQL Server Management Studio是一个图形用 户界面,用以交互地设计和测试Transact-SQL语句、批处理和脚本。 本节通过SELECT查询语句以及数据库和表的操作语句来介绍Transact-SQL的基本使 用。因此,本节首先介绍一下查询分析器的使用,然后再介绍如何使用查询分析器来执行 SQL语句。 5.2.1 在SQL Server Management Studio中执行SQL语句 在SQL Server Management Studio中,用户可输入Transact-SQL语句,执行语句并在结 果窗口中查看结果。用户也可以打开包含Transact-SQL语句的文本文件,执行语句并在结 果窗口中查看结果。 SQL Server Management Studio提供: y 用于输入Transact-SQL语句的自由格式文本编辑器。 y 在Transact-SQL语句中使用不同的颜色,以提高复杂语句的易读性。 y 对象浏览器和对象搜索工具,可以轻松查找数据库中的对象和对象结构。 y 模板,可用于加快创建SQL Server对象的Transact-SQL语句的开发速度。模板是包 含创建数据库对象所需的Transact-SQL语句基本结构的文件。 y 用于分析存储过程的交互式调试工具。 y 以网格或自由格式文本窗口的形式显示结果。 y 显示计划信息的图形关系图,用以说明内置在Transact-SQL语句执行计划中的逻辑 步骤。这使程序员得以确定在性能差的查询中,具体是哪一部分使用了大量资源。 之后,程序员可以试着采用不同的方法更改查询,使查询使用的资源减到最小的 新概念 SQL Server 2005 教程 112 同时仍返回正确的数据。 y 使用索引优化向导分析Transact-SQL语句以及它所引用的表,以了解通过添加其他 索引是否可以提高查询的性能。 关于如何在SQL Server Management Studio中执行SQL语句,可以参考2.4.1节的内容。 5.2.2 数据查询 数据库存在的意义在于将数据组织在一起,以方便查询。“查询”的含义就是用来描述 从数据库中获取数据和操纵数据的过程。 SQL语言中最主要、最核心的部分是它的查询功能。查询语言用来对已经存在于数据 库中的数据按照特定的组合、条件表达式或者一定次序进行检索。其基本格式是由SELECT 子句、FROM子句和WHERE子句组成的SQL查询语句: SELECT <列名表> FROM <表或视图名> WHERE <查询限定条件> 也就是说,SELECT指定了要查看的列(字段),FROM指定这些数据来自哪里(表或 者视图),WHERE则指定了要查询哪些行(记录)。 提 示 在SQL语言中,SELECT子句除了进行查询外,其他的很多功能也都离不开SELECT 子句,例如,创建视图是利用查询语句来完成的;插入数据时,在很多情况下是从另外一 个表或者多个表中选择符合条件的数据。所以查询语句是掌握SQL语言的关键。 完整的SELECT语句的用法如下所示: SELECT select_list [INTO new_talbe] FROM table_source [WHERE search_condition] [GROUP BY group_by_expression] [HAVING search_condition] [ORDER BY order_expression [ASC | DESC]] 其中,带有方括号的子句均是可选子句,大写的单词表示SQL的关键字,而小写的单 词或者单词组合表示表(视图)名称或者给定条件。具体符号含义可查阅附录A。 下面以bookdb数据库为例,来介绍各个子句的使用。首先在book表和authors表中加入 几条记录。这里只是为了作为例子来介绍,因此可以自行加入几条记录。但是应注意的是, 由于book中参考了authors表中的记录,因此,应先在authors表中加入记录,而后再在book 表中加入记录。 1. 查询表中所有的列 使用格式:SELECT * FROM table_name 例如,要查询book表中的所有书籍的信息,可在SQL查询分析器中输入如下命令: 113 第5章 Chapter 05 Transact-SQL及其程序设计基础 SELECT * FROM book 然后在工具栏上单击“执行”按钮或者按F5键,即可看到所有书籍的信息,如图5.2所 示。 图 5.2 查询 book 表中的所有书籍的信息 2. 查询表中指定的列 使用格式:SELECT column_name[,…n] FROM table_name 说明:多个字段用逗号“,”隔开。 例如,要查询所有书籍的名称和价格,可输入下面的SQL语句: SELECT book_name,price FROM book 按F5键,结果如图5.3所示。 图 5.3 查询所有书籍的名称和价格 可以重新排列列的次序,在SELECT后的列名的顺序决定了显示结果中的列序。如果 想把价格放在前面,则上面的SQL语句应该写成: SELECT price,book_name FROM book 执行此语句,可看到结果中价格放在了前面。 3. 使用单引号加入字符串 例如,要查询所有书籍的名称和价格,并在价格前面显示字符串“价格为:”,可输 入下面的SQL语句: 输入查询命令 查询结果 选择数据库 新概念 SQL Server 2005 教程 114 SELECT book_name,'价格为:',price FROM book 按F5键,结果如图5.4所示。 图 5.4 在价格前面显示字符串 4. 使用别名 在显示结果时,可以指定以别名来代替原来的字段名称,总共有3种方法: y 采用“别名 AS 字段名称”的格式。 y 采用“字段名称 别名”的格式。 y 采用“别名=字段名称”的格式,其中别名用单引号括起来。 例如,查询所有书籍的名称和价格,并在标题栏中显示“书名”和“价格”字样,而 不是显示book_name和price,可输入下面的SQL语句: SELECT book_name AS 书名,price AS 价格 FROM book 或者 SELECT book_name 书名,price 价格 FROM book 或者 SELECT '书名'=book_name,'价格'=price FROM book 按F5键,结果如图5.5所示。 图 5.5 使用别名 5. 查询特定的记录 使用WHERE关键词来限定查询的条件。例如,要查询《Windows 2003 Server网络管理》 一书的信息,则可以输入以下SQL语句: SELECT * FROM book WHERE book_name='Windows 2003 Server网络管理' 按F5键,结果如图5.6所示。 图 5.6 查询《Windows 2003 Server 网络管理》一书的信息 6. 对查询结果进行排序 在SELECT语句中,可以使用ORDER BY子句对查询结果进行排序。其语法格式为: 标题栏中显示别名 115 第5章 Chapter 05 Transact-SQL及其程序设计基础 [ORDER BY order_expression [ASC | DESC]] 其中各项含义如下: y order_expression为排序的表达式,可以是一个列、列的别名、表达式或者非零的 整数值,而非零的整数值则表示列、别名或者表达式在选择列表中的位置。 y 后续关键字ASC表示升序排列,DESC表示降序排列,默认值为ASC,排序时,空 值(NULL)被认为是最小值。 注 意 ntext、text和image数据类型的字段不能用作ORDER BY排序的字段。关于数据类型 的介绍详见5.3.2小节。 例如,依照价格高低来显示所有书籍 的信息,输入以下SQL语句: SELECT * FROM book ORDER BY price DESC 按F5键,结果如图5.7所示。 7. 多表查询 使用SELECT可以对多个表进行查询。例如,要显示书籍的书名和作者,此时就涉及 到多个表的查询。因为书名在book表中,而作者姓名则在authors表中。限定条件则为book 表中的author_id字段和authors表的author_id字段的值相同。 输入下面的SQL语句: SELECT book.book_name,authors.author_name FROM book,authors WHERE book.author_id=authors.author_id 按F5键,结果如图5.8所示。 8. 消除重复的行 使用DISTINCT关键字来消除重复行。例如,查询所有书籍所属 的出版社。输入SQL语句如下: SELECT DISTINCT publisher FROM book 按F5键,执行结果如图5.9所示。 5.2.3 数据插入和删除 新增数据使用INSERT语句,其语法如下: INSERT [INTO] table_name [column_list] VALUES(data_values) 其中各项参数的含义如下: 图 5.8 多表查询结果 图 5.9 消除重复的行 图 5.7 依照价格高低排列结果 新概念 SQL Server 2005 教程 116 y table_name 要新增数据的表或者视图名称。 y column_list 要新增数据的字段名称,若没有指定字段列表,则指全部字段。 y data_values 新增记录的字段值,必须和column_list相对应,也就是说每一个字段 必须对应到一个字段值。 在表authors中插入一笔记录,即新增一个作者。输入SQL语句如下: INSERT authors(author_id,author_name) VALUES(3,'张英魁') 按F5键,自动打开“消息”窗口,显示如下信息: (1 行受影响) 表示加入了一笔记录。使用SELECT语句查询authors表,可看到新增加的记录。输入如 下SQL语句: SELECT * FROM authors 执行结果如图5.10所示,可看到新增加的第3个 作者。 要删除数据,可以使用DELETE语句,其语法 如下: DELETE table_name WHERE search_condition 其中table_name是要删除数据的表的名称;search_condition是用来查找要删除数据的条 件。 例如,删除book表中《Windows Vista看图速成》一书的记录,可以输入以下SQL语句: DELETE book WHERE book_name='Windows Vista看图速成' 按F5键执行后,即可将该记录删除。可以使用查询语句来查询执行删除的结果。 如果要删除表中所有的行,则可以使用TRUNCATE语句,其语法格式如下: TRUNCATE TABLE table_name 下面的例子即为删除authors表中的所有数据: TRUNCATE TABLE authors 提 示 TRUNCATE TABLE在功能上与不带WHERE子句的DELETE语句相同:二者均删除 表中的全部行。DELETE语句每次删除一行,并在事务日志中为所删除的每行记录一项。 TRUNCATE TABLE通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中 记录页的释放。因此TRUUNCATE TABLE比DELETE速度快,且使用的系统和事务日志资 源少。另外,TRUNCATE TABLE删除表中的所有行,但表结构及其列、约束、索引等保 持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,可以使用 DELETE。如果要删除表定义及其数据,可以使用DROP TABLE语句。 图 5.10 查看新增加的记录 117 第5章 Chapter 05 Transact-SQL及其程序设计基础 5.2.4 数据修改 在数据输入过程中,可能会出现输入错误,或者是因时间变化而需要更新数据。这都 需要修改数据。可以在企业管理器中一笔一笔地修改记录,但是使用SQL语言可能会更快 捷。 修改数据需要使用UPDATE语句,其语法如下: UPDATE table_name SET column[WHERE condition] 例如,将authors表中作者为“王小明”全部改为“王晓明”,SQL语句如下: UPDATE authors SET author_name='王晓明' WHERE author_name='王小明' 可以使用SELECT语句来查看执行结果。 5.2.5 使用函数 SQL Server提供了内置函数,使用这些函数,可以插入当前日期,对文本和图像进行 操作等。 例如,在orderform表中,提交一笔订单,在插入数据时,即可使用GETDATE()函 数来获取当前的日期。为了保持数据完整性,首先在clients表中插入一个客户,然后再在 orderform表中提交一笔订单。输入下面的SQL语句: INSERT clients VALUES(1,'刘明耀','北京市海淀区') INSERT orderform VALUES(1,2,50,GETDATE(),1) 按F5键,然后使用SELECT语句可查看执行结果: SELECT * FROM orderform 结果如图5.11所示。 图 5.11 插入的订单记录 可以将其视为主动画的子动画。 提 示 SQL Server中的内置函数的详细内容,可查阅附录C。 5.2.6 使用公式 在列出现的位置上,可以使用公式对查询结果进行计算。例如,要查询所有订单中的 书名、数量和总额。此时,就可以使用公式来计算总额。输入的SQL语句如下: SELECT book.book_name,orderform.book_number, '总额为:',(book.price*orderform.book_number) FROM orderform,book WHERE orderform.book_id=book.book_id 新概念 SQL Server 2005 教程 118 按F5键,执行结果如图5.12所示。 图 5.12 查询订单总额 5.2.7 数据库的操作语句 在第3章介绍了使用SQL Server Management Studio创建数据库的方法,使用SQL语句同 样也可创建数据库,并对数据库进行修改和删除。下面做简单介绍,有关数据库操作的详 细信息请参考附录B。 1. 创建数据库 创建数据库可以使用CREATE DATABASE语句。 例如,建立一个名为test的数据库,可以输入如下的SQL语句: CREATE DATABASE test 按F5键,系统提示消息如下: 命令已成功完成。 打开SQL Server Management Studio,可看到新建立的数据库test。如果SQL Server Management Studio处于打开状态,可执行“操作”菜单中的“刷新”命令,来查看新建立 的数据库。 使用一条CREATE DATABASE语句即可创建数据库以及存储该数据库的文件。SQL Server分两步实现CREATE DATABASE语句: SQL Server使用model数据库的副本初始化数据库及其元数据。 SQL Server使用空页填充数据库的剩余部分,除了包含记录数据库中空间使用情 况以外的内部数据页。 如果要指定数据文件和事务日志文件,则可以使用ON和LOG ON关键字,并可以指定 数据文件和事务日志文件的大小。 例如,要创建一个销售数据库,并设定数据文件为“d:\销售数据.MDF”,大 小 为 5MB, 最大为20MB,每次增长5MB。事务日志文件为“d:\销售数据日志.LDF”,大小为5MB, 最大为10MB,每次增长为1MB。则创建的SQL语句和执行结果如图5.13所示。 119 第5章 Chapter 05 Transact-SQL及其程序设计基础 图 5.13 创建销售数据库 2. 修改数据库 在建立数据库后,可根据需要修改数据库的设置。修改数据库可以使用ALTER DATABASE语句。 例如,为销售数据库新增一个逻辑名为“销售数据2”的数据文件,其大小及其最大值 分别为10MB和50MB。输入的SQL语句和执行结果如图5.14所示。 图 5.14 修改销售数据库 3. 使用和删除数据库 使用和删除数据库,可以使用USE和DROP语句。其语法如下: USE DATABASE database_name DROP DATABASE database_name 其中database_name表示要使用或者删除的数据库。 例如,可以使用如下SQL语句来删除销售数据库: DROP DATABASE 销售数据库 执行结果如图5.15所示。 指定数据文件 指定日志文件 完成后的提示信息 新概念 SQL Server 2005 教程 120 图 5.15 删除销售数据库 提 示 如果不知道目前的SQL Server服务器中包含哪些数据库,可以执行sp_helpdb存储过 程,使用方式为:EXEC sp_helpdb。如果后面再加上数据库名,则表示查询特定的数据库。 5.2.8 表的操作语句 同样,可以使用SQL语言创建表,也可以修改和删除表。下面进行简单介绍,详细内 容请参考附录B。 1. 表的创建 提供了CREATE TABLE语句来建立表,其语法如下: CREATE TABLE table_name ( column_name1 data_type [NULL | NOT NULL] [PRIMARY | UNIQUE] [FOREIGN KEY [(column_name)]] REFERENCES ref_table [(ref_column)] [column_name2 data_type …] … ) 其中各参数含义如下: y table_name 要创建的表的名称。 y column_name1 第一个字段名称。 y data_type 指定字段的数据类型。 其余为字段属性设置参数,将在下面介绍。 (1)基本用法 在test数据库中创建一个clients表,SQL语句如下: USE test CREATE TABLE clients ( client_id int, client_name char(8), address char(50) ) 121 第5章 Chapter 05 Transact-SQL及其程序设计基础 其中第1行表示使用test数据库,创建的表clients中包含3个字段:client_id、client_name 和address。数据类型分别为整型、字符型(长度为8)和字符型(长度为50)。 提 示 USE语句只要在第一次使用即可,后续的SQL语句都是作用在该数据库中。若要使用 其他的数据库,才需要再次执行USE语句。 (2)段属性参数 除了可以设置字段的数据类型外,还可以利用一些属性参数来对字段做出限定。例如, 将字段设置为主键,限制字段不能为空等。 常用的属性参数如下: y NULL和NOT NULL 限制字段可以为NULL(空),或者NOT NULL(不能为空)。 y PRIMARY KEY 设置字段为主键。 y UNIQUE 指定字段具有唯一性。 下面的SQL语句是在test数据库中建立一个book表,并指定book_id为主键,而 book_name为非空: CREATE TABLE book ( book_id int NOT NULL PRIMARY KEY, book_name char(8) NOT NULL, author_id char(50) ) CREATE TABLE book ( book_id int NOT NULL PRIMARY KEY, book_name char(8) NOT NULL, author_id char(50) (3)与其他表建立关联 表的字段可能参考到其他表的字段,这就需要将两个表建立关联。此时,就可以使用 如下的语法: FOREIGN KEY REFERENCE ref_table (ref_column) 例如,可以将book表中的author_id字段关联到authors表的author_id字段。在企业管理器 中将上面创建的book表删除,然后执行下面的语句: CREATE TABLE authors( author_id int NOT NULL PRIMARY KEY, author_name char(8) NOT NULL, address char(50) NULL ) CREATE TABLE book ( book_id int NOT NULL PRIMARY KEY, book_name char(8) NOT NULL, author_id int FOREIGN KEY REFERENCES authors (author_id) ) 上面的语句首先创建一个authors表,然后创建book表,并将author_id字段关联到authors 新概念 SQL Server 2005 教程 122 表的author字段。 提 示 在创建book表时,由于将author_id字段关联到了authors表,因此authors表必须存在。 这也是上面首先创建authors表的原因。 2. 修改表 SQL语言提供了ALTER TABLE语句来修改表的结构。基本语法如下: ALTER TABLE table_name ADD [column_name data_type] [PRIMARY KEY | CONSTRAIN] [FOREIGN KEY (column_name) REFERENCES ref_table_name (ref_column_name)] DROP [CONSTRAINT] constraint_name | COLUMN column_name 其中各参数含义如下: y ADD 增加字段,后面为属性参数设置。 y DROP 删除限制或者字段。CONSTRAINT表示删除限制;COLUMN表示删除字 段。 例如,在test数据库中给book表增加一个“简介”字段: ALTER TABLE book ADD 简介 text 3.删除关联和表 使用SQL语言要比使用企业管理器删除表容易得多。 删除表的语法如下: DROP TABLE table_name 例如,要删除book表,可执行下述SQL语句: DROP TABLE book 5.3 Transact-SQL程序设计基础 SQL虽然和高级语言不同,但是它本身也具有运算和流控制等功能,也可以利用SQL 语言进行编程。因此,就需要了解SQL语言的基础知识。本节主要介绍Transact-SQL语言程 序设计的基础概念。 5.3.1 标识符 在SQL Server中,标识符就是指用来定义服务器、数据库、数据库对象和变量等的名 称。可以分为常规标识符和定界标识符。 123 第5章 Chapter 05 Transact-SQL及其程序设计基础 1. 常规标识符 常规标识符就是不需要使用分隔标识符进行分隔的标识符。常规标识符符合标识符的 格式规则。在Transact-SQL语句中使用常规标识符时不用将其分隔。 例如: SELECT * FROM TableX WHERE KeyCol = 124 这里,TableX和KeyCol就是两个常规标识符。 在SQL Server 2005中,常规标识符的格式规则取决于数据库的兼容级别,兼容级别可 以用存储过程sp_dbcmptlevel来设置。当兼容级别为 80 时,规则是: y 第一个字符必须是Unicode 2.0标准所定义的字母、下画线(_)、at符号(@)和 数字符号(#)。 y 后续字符可以是Unicode标准2.0所定义的字母、来自基本拉丁字母或其他国家/地 区脚本的十进制数字、at符号(@)、美元符号($)、数字符号(#)或下画线 (_)。 y 标识符不能是Transact-SQL的保留字。SQL Server保留其保留字的大写和小写形 式。 y 不允许嵌入空格或其他特殊字符。 y 常规标识符和分隔标识符包含的字符数必须在1~128之间。对于本地临时表,标识 符最多可以有116个字符。 注 意 在SQL Server中,某些处于标识符开始位置的符号具有特殊意义。以at符号(@)开 始的标识符表示局部变量或参数;以双at符号(@@)开始的标识符表示全局变量。以一 个数字符号(#)开始的标识符表示临时表或过程。以双数字符号(##)开始的标识符表 示全局临时对象。 2. 分隔标识符 在Transact-SQL语句中,对不符合所有标识符规则的标识符必须进行分隔。符合标识 符格式规则的标识符可以分隔,也可以不分隔。 例如,下面语句中的My Table和order均不符合标识符规则,其中My Table中间出现了 空格,而order为Transact-SQL的保留字,因此必须使用分隔符中括号([ ])进行分隔: SELECT * FROM [My Table] WHERE [order] = 10 分隔标识符在下列情况下使用: y 当在对象名称或对象名称的组成部分中使用保留字时 推荐不要使用保留关键字 作为对象名称。从SQL Server早期版本升级的数据库可能含有标识符,这些标识符 包括早期版本中未保留而在SQL Server 2005中保留的字。可用分隔标识符引用对 象直到可改变其名称。 y 当使用未被列为合法标识符的字符时 SQL Server允许在分隔标识符中使用当前 新概念 SQL Server 2005 教程 124 代码页中的任何字符。但是,不加选择地在对象名称中使用特殊字符将使SQL语 句和脚本难以阅读和维护。 在SQL Server中,Transact-SQL所使用的分隔标识符类型有下面两种: y 被引用的标识符用双引号(")分隔开 例如:SELECT * FROM " My Table "。 y 括在括号中的标识符用方括号([ ])分隔 例如:SELECT * FROM [My Table]。 分隔标识符的格式规则是: y 分隔标识符可以包含与常规标识符相同的字符数(1~128个,不包括分隔符字符)。 本地临时表标识符最多可以包含116个字符。 y 标识符的主体可以包含当前代码页内字母(分隔符本身除外)的任意组合。例如, 分隔符标识符可以包含空格、对常规标识符有效的任何字符以及下列任何字符: 代字号(~)、连字符(-)、惊叹号(!)、左括号({)、百分号(%)、右括号 (})、插入号(^)、撇号(')、and号(&)、句号(.)、左圆括号(()、反斜 杠(\)、右圆括号())、重音符号(`)。 使用引号分隔标识符时,仅当QUOTED_IDENTIFIER选项设置为 ON 时才有效。 QUOTED_IDENTIFIER称作连接选项。默认情况下,当用于SQL Server的Microsoft OLE DB 提供程序和SQL Server ODBC驱动程序连接时,将QUOTED_IDENTIFIER设置为ON。默认 情况下,DB-Library不将 QUOTED_IDENTIFIER设置为 ON。不管使用何种接口,个别应 用程序或用户可随时更改设置。 SQL Server提供了多种方法来指定该选项。例如,在SQL Server企业管理器和SQL查询 分析器中,该选项可在对话框中设置。在Transact-SQL中,可以使用SET QUOTED_ IDENTIFIER、sp_dboption的quoted identifier选项或sp_configure的user options选项将此选项 设为多种级别。例如,打开和关闭该选项的SET语句如下: SET QUOTED_IDENTIFIER ON SET QUOTED_IDENTIFIER OFF 注 意 如果打开了QUOTED_IDENTIFIER选项,双引号只能用于分隔标识符,不能用于分 隔字符串;单引号必须用来包含字符串,不能用于分隔标识符。如果关闭了该选项,引号 不能用于分隔标识符,而是用括号作为分隔符。单引号或双引号可用于包含字符串。 3. 使用标识符 数据库对象的名称被看成是该对象的标识符。SQL Server中的每一内容都可带有标识 符。服务器、数据库和数据库对象(例如表、视图、列、索引、触发器、过程、约束及规 则等)都有标识符。大多数对象要求带有标识符,但对有些对象(如约束),标识符是可 选项。 在SQL Server 2005中,一个对象的全称语法格式为: server.database.owner.object 125 第5章 Chapter 05 Transact-SQL及其程序设计基础 其中server为服务器名,database为数据库名,owner为所有者,object为对象名。 例如,在服务器MyServer中,test数据库中的sysusers表的全称就是: MyServer.test.dbo.sysusers 在实际使用时,使用全称比较繁琐,因此经常使用简写格式。可用的简写格式包含下 面几种: server.database..object server..owner.object server…object database.owner.object database..object owner.object object 在上面的简写格式中,没有指明的部分使用如下的默认设置值: y 服务器 本地服务器。 y 数据库 当前数据库。 y 所有者 在指定的数据库中与当前连接会话的登录标识相对应的数据库用户或者 数据库所有者。 例如,一个用户名为bookadm的用户登录到MyServer服务器上,并使用book数据库。 使用下述语句创建了一个MyTable表: CREATE TABLE MyTable ( column1 int, column2 char(20) ) 则表MyTable的全称就是MyServer.book.bookadm.MyTable。 5.3.2 数据类型 数据类型是指列、存储过程参数、表达式和局部变量的数据特征,它决定了数据的存 储格式,代表了不同的信息类型。包含数据的对象都具有一个相关的数据类型,此数据类 型定义对象所能包含的数据种类(字符、整数、二进制数等)。 SQL Server提供了各种系统数据类型。除了系统数据类型外,在SQL Server中,还可以 自定义数据类型。用户定义的数据类型是在系统数据类型的基础上,使用存储过程 sp_addtype所建立的数据类型。 提 示 在SQL Server 2005中,所有系统数据类型名称都是不区分大小写的。另外,用户定 义数据类型是在已有的系统数据类型基础上生成的,而不是定义一个存储结构的新类型。 在SQL Server 2005中,以下对象可以具有数据类型: y 表和视图中的列; 新概念 SQL Server 2005 教程 126 y 存储过程中的参数; y 变量; y 返回一个或多个特定数据类型数据值的Transact-SQL函数; y 具有一个返回代码的存储过程(返回代码总是具有integer数据类型)。 指定对象的数据类型定义了该对象的4个特性: y 对象所含的数据类型,如字符、整数或二进制数。 y 所存储值的长度或它的大小。image、binary和varbinary数据类型的长度以字节定义。 任何数字数据类型的长度是指保存此数据类型所允许的数字个数所需要的字节 数。string和Unicode数据类型的长度以字符数定义。 y 数字精度(仅用于数字数据类型) 精度是数字可以包含的数字个数。例如,smallint 对象最多能拥有5个数字,所以其精度为5。 y 数值小数位数(仅用于数字数据类型) 小数位数是能够存储在小数点右边的数 字个数。例如,int对象不能含有小数点,小数位数为0。money对象的小数点右边 最多可以有4个数字,小数位数为4。 1. 系统数据类型 可以按照存放在数据库中的数据的类型对SQL Server提供的系统数据类型进行分类, 如表5.1所示。 表5.1 SQL Server 2005提供的系统数据类型 分类 数据类型定义符 整数型 bigint、int、smallint、tinyint 逻辑数值型 bit 小数数据类型 decimal、numeric 货币型 money、smallmoney 近似数值型 float、real 字符型 char、varchar、text Unicode字符型 Nchar、nvarchar、ntext 二进制数据类型 binary、varbinary、image 日期时间类型 datetime、smalldatetime 其他数据类型 cursor、sql_variant、table、timestamp、uniqueidentifier (1)整数型 整数类型包括bigint、int、smallint和tinyint共4种,其中bigint是SQL Server 2005中新增 的一种类型。 整型数据由负整数或正整数组成,如-15、0、5和2509。在SQL Server 2005中,整型数 据使用bigint、int、smallint和tinyint数据类型存储。bigint数据类型可存储的数字范围比int 数据类型广。int数据类型比smallint数据类型的存储范围大,而smallint的数值范围又比tinyint 类型大。 127 第5章 Chapter 05 Transact-SQL及其程序设计基础 各种类型能存储的数值的范围如下: y bigint数据类型 大整数型,长度为8个字节,可以存储从-263(-9 223 372 036 854 775 808)~263-1(9 223 372 036 854 775 807)范围内的数字。 y int数据类型 整数型,长度为4个字节,可存储范围是-231(-2 147 483 648)~ 231-1(2 147 483 647)。 y smallint数据类型 短整数型,长度为2个字节,可存储范围只有-231(-32 768)~231-1 (32 767)。 y tinyint数据类型 微短整数型,长度为1个字节,只能存储0~255范围内的数字。 例如,下面的语句创建了一个表Int_table,其中的4个字段分别使用这4种整数类型: USE test CREATE TABLE Int_table ( c1 tinyint, c2 smallint, c3 int, c4 bigint, ) INSERT Int_table VALUES (50,5000,50000,500000) SELECT * FROM Int_table 执行结果是显示出表Int_table中的一笔记录,它包含了4种数据类型。 注 意 上面的SQL语句可以在自己另外创建的数据库中进行,对于下面的例子,本书都在test 数据库中进行。 (2)小数数据类型 也称为精确数据类型,它们由两部分组成,其数据精度保留到最低有效位,所以它们 能以完整的精度存储十进制数。 在声明小数数据类型时,可以定义数据的精度和小数位。声明格式如下: decimal[(p[, s])] 和numeric[(p[, s])] 各参数含义如下: y p(精度) 指定小数点左边和右边可以存储的十进制数字的最大个数。精度必须 是从1到最大精度之间的值。最大精度为38。使用最大精度时,有效值从-1038 +1~1038-1。 y s(小数位数) 指定小数点右边可以存储的十进制数字的最大个数。小数位数必 须是从0~p之间的值。默认小数位数是0,因而0<= s <= p。最大存储大小基于精度 而变化。 例如,在下面的表Decimal_table中,字段c1就是一个decimal数据类型: CREATE TABLE Decimal_table 新概念 SQL Server 2005 教程 128 ( c1 decimal(3,2) ) INSERT Decimal_table VALUES (4.5678) SELECT * FROM Decimal_table 执行结果如下: c1 ---------- 4.57 提 示 在上面的结果显示中,不再使用图形来表示,而使用上述方式来表示执行结果。下 面的例子也将使用这种方式表示结果。 在为小数数值型数据赋值时,应保证所赋数据整数部分的位数小于或者等于定义的长 度,否则会出现溢出错误。 例如,给Decimal_table插入一笔记录,在SQL查询分析器中执行下面语句: INSERT Decimal_table VALUES (45.678) 执行出现错误,并出现如下消息: 消息8115,级别16,状态8,第1 行 将numeric 转换为数据类型numeric 时出现算术溢出错误。 语句已终止。 这是由于45.678的整数部分超出了定义的长度造成的。 Decimal数据包含存储在最小有效数上的数据。在SQL Server中,小数数据使用 decimal 或numeric数据类型存储。存储decimal或numeric数值所需的字节数取决于该数据的数字总 数和小数点右边的小数位数。例如,存储数值192 83.293 83比存储1.1需要更多的字节。具 体存储长度随其精度的变化而改变,如表5.2所示。 表5.2 存储字节长度和数据精度的关系 精度 存储字节长度 1~9 5 10~19 9 20~28 13 29~38 17 提 示 在SQL Server中,numeric数据类型等价于decimal数据类型。但是只有numeric可以用 于带有identity关键字的列(字段)。 (3)近似数值型 并非数据类型范围内的所有数据都能精确地表示,因此SQL Server提供了用于表示浮 129 第5章 Chapter 05 Transact-SQL及其程序设计基础 点数字数据的近似数值数据类型。 近似数值数据类型不能精确记录数据的精度,它们所保留的精度由二进制数字系统的 精度决定。SQL Server提供了两种近似数值数据类型: y float [ ( n ) ] -1.79308~1.79308之间的浮点数字数据。n为用于存储科学记数法float 数尾数的位数,同时指示其精度和存储大小。n必须为1~53之间的值,它同精度和 存储字节的关系如表5.3所示。 y real数据类型 -3.4038~3.4038之间的浮点数字数据。存储大小为4字节。 表5.3 n与精度和存储字节之间的关系 n 精度 存储字节长度 1~24 7位数 4字节 25~53 15位数 8字节 提 示 float和real通常按照科学记数法来表示,即以1.79E+38的方式表示。 (4)字符型 字符串存储时采用字符型数据类型。字符数据由字母、符号和数字组成。例如,“928”、 “Johnson”和“(0*&(%B99nh jkJ”都是有效的字符数据。 提 示 字符常量必须包括在单引号(')或双引号(")中。建议用单引号括住字符常量。因 为当QUOTED IDENTIFIER选项设为ON时,有时不允许用双引号括住字符常量。当使用 单引号分隔一个包括嵌入单引号的字符常量时,用两个单引号表示嵌入单引号。 在SQL Server中,字符数据使用char、varchar和text数据类型存储。当列中各项的字符 长度可变时可用varchar 类型,但任何项的长度都不能超过8 KB。当列中各项为同一固定长 度时使用char类型(最多8KB)。text 数据类型的列可用于存储大于8KB的ASCII字符。例 如,由于HTML文档均由ASCII字符组成且一般长于8KB,所以用浏览器查看之前应在SQL Server中存储在text列中。 建议字符列长度的定义不超过所存储的字符数据可能的最大长度,以节省存储空间。 另外,若要在SQL Server中存储国际化字符数据,请使用nchar、nvarchar和ntext数据类型。 支持多语言的网络站点应考虑使用Unicode的nchar或nvarchar 数据类型,以尽量减少字符转 换问题。如果希望列中的数据值大小接近一致或者列中的数据值大小显著不同,则可以考 虑使用char或varchar。 char、varchar和text的3种类型的定义方式如下: y char[(n)] 长度为n个字节的固定长度且非Unicode的字符数据。n必须是一个介于 1~8000之间的数值。存储大小为n个字节。 y varchar[(n)] 长度为n个字节的可变长度且非Unicode的字符数据。n必须是一个介 于1~8000之间的数值。存储大小为输入数据的字节的实际长度,而不是n个字节。 新概念 SQL Server 2005 教程 130 所输入的数据字符长度可以为零。 y text数据类型 也是用来声明变长的字符数据。在定义过程中,不需要指定字符的 长度。最大长度为231-1(2 147 483 647)个字符。当服务器代码页使用双字节字 符时,存储量仍是2 147 483 647个字节。存储大小可能小于2 147 483 647字节(取 决于字符串)。SQL Server会根据数据的长度自动分配空间。 例如,下面的SQL语句将局部变量MyCharVar声明为char类型,长度为25: DECLARE @MyCharVar CHAR(25) SET @MyCharVar = 'This is a string' 下面则是使用两个单引号来表示嵌入单引号: SET @MyCharVar = 'This is a ''string''' 如果要存储的数据比允许的字符数多,则数据就会被截断。例如,如果某列被定义为 char(10)并且值“This is a really long character string”被存储到该列中,则SQL Server将该字 符串截断为“This is a”。 CHAR函数可以把一个整数转换为ASCII字符。当确定控制字符时(比如回车或换行), 这是很有用的。在字符串中用CHAR(13)和CHAR(10)产生一个回车并生成一个新行。 PRINT 'First line.' + CHAR(13) + CHAR(10) + 'Second line.' 执行结果为: First line. Second line. 提 示 PRINT函数用于打印字符串,将其显示在屏幕上。 (5)逻辑数值型 SQL Server支持逻辑数据类型bit,它可以存储整型数据1、0或NULL。如果输入0以外 的其他值时,SQL Server均将它们当作1看待。 SQL Server优化用于bit列的存储。如果一个表中有不多于8个的bit列,这些列将作为一 个字节存储。如果表中有9~16个bit列,这些列将作为两个字节存储。更多列的情况依此类 推。 注 意 不能对bit类型的列(字段)使用索引。 例如,下面是使用bit数据类型的例子: CREATE TABLE Bit_table ( c1 bit, c2 bit, 131 第5章 Chapter 05 Transact-SQL及其程序设计基础 c3 bit ) INSERT Bit_table VALUES(12,1,0) SELECT * FROM Bit_table 执行结果为: c1 c2 c3 --------------------- 1 1 0 (6)货币型 货币数据表示正的或负的货币值。在SQL Server中使用money和smallmoney数据类型存 储货币数据。货币数据存储的精确度为4位小数。 money和smallmoney数据类型存储范围和占用字节如下: y money数据类型 可存储的货币数据值介于-263(-922 337 203 685 477.5808)与 263-1 (+922 337 203 685 477.5807)之间,精确到货币单位的千分之十。存储大小为 8个字节。 y smallmoney数据类型 可存储的货币数据值介于-214 748.3648与+214 748.364 7之 间,精确到货币单位的千分之十。存储大小为4个字节。 货币数据不需要用单引号(')括起来。但是,货币数值之前必须带有适当的货币符号。 例如,若要指定100英镑,则使用£100。若要指定100美元,则使用$100。不同货币的符号 可参考SQL Server 2000的帮助文档。 下面是使用货币数据类型的例子: CREATE TABLE Money_table ( c1 money, c2 smallmoney ) INSERT Money_table VALUES ($12345678,$1234) SELECT * FROM Money_table 执行结果如下: c1 c2 ------------------------------------- 12345678.00 1234.00 (7)二进制数据类型 二进制数据由十六进制数表示。例如,十进制数245等于十六进制数F5。在SQL Server 2005中,二进制数据使用binary、varbinary和image数据类型存储。 声明为binary数据类型的列在每行中都是固定的长度(最多为8KB)。声明为varbinary 数据类型的列,各项所包含的十六进制数字的个数可以不同(最多为8KB)。image数据列 可以用来存储超过8KB的可变长度的二进制数据,例如,Word文档、Excel电子表格、位图 图像、图形交换格式(GIF)文件和联合图像专家组(JPEG)文件。 声明格式如下: 新概念 SQL Server 2005 教程 132 y binary[(n)] 固定长度的n个字节二进制数据。n必须从1~8000。存储空间大小为n+4 个字节。 y varbinary[(n)] n个字节变长二进制数据。n必须从1~8000。存储空间大小为实际输 入数据长度+4个字节,而不是n个字节。输入的数据长度可能为0字节。 y image 可变长度二进制数据介于0与231-1(2 147 483 647)字节之间。 二进制常量以0x(一个零和小写字母x)开始,后面跟着位模式的十六进制表示。例如, 0x2A表示十六进制的值2A,它等于十进制的数42或单字节位模式00101010。 下面是使用二进制数据类型的例子: CREATE TABLE Binary_table ( c1 binary(10), c2 varbinary(20), c3 image ) INSERT Binary_table VALUES (0x123,0xfffff,0x14fffff) SELECT * FROM Binary_table 执行结果如下: c1 c2 c3 ----------------------------------------------------------------------- 0x01230000000000000000 0x0FFFFF 0x014FFFFF (8)日期时间类型 SQL Server提供了专门的日期时间类型。日期和时间数据由有效的日期或时间组成。 例如,“4/01/98 12:15:00:00:00 PM”和“1:28:29:15:01 AM 8/17/98”都是有效的日期和时 间数据。 在SQL Server中,日期和时间数据使用datetime和smalldatetime数据类型存储: y datetime 从1753年1月1日到9999年12月31日的日期和时间数据,精确度为3‰ 秒(s)(等于3ms或0.003s)。表5.4为用户输入的值和SQL Server自动把值调整 到.000、.003或.007s的增量后的值。 y smalldatetime 从1900年1月1日到2079年6月6日的日期和时间数据精确到分钟 (min)。29.998s或更低的smalldatetime值向下舍入为最接近的分钟,29.999s或更 高的 smalldatetime值向上舍入为最接近的分钟。 下面是一个使用smalldatetime数据类型的例子: SELECT CAST('2000-05-08 12:35:29.998' AS smalldatetime) 执行结果为: 2000-05-08 12:35:00 由于最后是29.998s,而smalldatetime数据类型精确到分钟,故执行结果将秒舍弃,最 终结果为12:35。 133 第5章 Chapter 05 Transact-SQL及其程序设计基础 表5.4 用户输入的值和SQL Server自动调整后的值 输入的值 SQL Server调整后的值 01/01/98 23:59:59.999 1998-01-02 00:00:00.000 01/01/98 23:59:59.995 01/01/98 23:59:59.996 01/01/98 23:59:59.997 或01/01/98 23:59:59.998 1998-01-01 23:59:59.997 01/01/98 23:59:59.992 01/01/98 23:59:59.993 01/01/98 23:59:59.994 1998-01-01 23:59:59.993 01/01/98 23:59:59.990 或01/01/98 23:59:59.991 1998-01-01 23:59:59.990 提 示 CAST函数的功能是将某种数据类型的表达式显式转换为另一种数据类型。AS后面 的数据类型就是要转换成为的数据类型。 SQL Server可以识别的日期格式有字母格式、数字格式和无分隔字符串格式3种。字符 格式允许使用以当前语言给出的月的全名(如April)或月的缩写(如Apr)来指定日期数 据。字符格式的日期需要放在单引号内。可用的字符型日期格式如下: Apr[il] [15][,] 1996 Apr[il] 15[,] [19]96 Apr[il] 1996 [15] [15] Apr[il][,] 1996 15 Apr[il][,][19]96 15 [19]96 apr[il] [15] 1996 apr[il] 1996 APR[IL] [15] 1996 [15] APR[IL] 数字格式允许用指定的数字月份指定日期数据。例如,5/20/97表示1997 年 5 月的第 20天,当使用数字日期格式时,在字符串中以斜杠(/)、连字符(-)或句号(.)作为分 隔符来指定月、日、年。例如,下面均表示1996年4月15日(--后面指明的是日期格式): [0]4/15/[19]96 -- (mdy) [0]4-15-[19]96 -- (mdy) [0]4.15.[19]96 -- (mdy) [04]/[19]96/15 -- (myd) 15/[0]4/[19]96 -- (dmy) 15/[19]96/[0]4 -- (dym) [19]96/15/[0]4 -- (ydm) [19]96/[04]/15 -- (ymd) 新概念 SQL Server 2005 教程 134 提 示 当语言被设置为us_english时,默认的日期顺序是mdy。可 以 使 用 SET DATEFORMAT 语句改变日期的顺序,根据所用的语言,它也会影响日期顺序。对SET DATEFORMAT的 设置决定了如何解释日期数据。如果顺序和设置不匹配,则该值不会被解释为日期(因为 它们超出了范围)或者被错误地解释。例如,根据不同的DATEFORMAT设置,12/10/08 能被解释为6种日期的一种。 无分隔字符串格式是指数字间不需要分隔符号,可以使用4、6、8位数字来表达日期。 如果使用4位表示,则只表示年份;如果使用6或者8位,月和日必须用两位。例如“19981207”、 “December 12,1998”。 SQL Server 2005可识别以下时间数据格式。用单引号(')把每一种格式括起来。下面 都是有效的时间格式: 14:30 14:30[:20:999] 14:30[:20.9] 4am 4 PM [0]4[:30:20:500]AM 可以用一个AM或PM后缀来表明时间值是在中午12点之前还是之后。AM或PM的大小 写可忽略。小时可以用12小时(h)或24小时(h)的时钟来指定。小时值解释如下: y 小时值0表示午夜(AM)后的小时,不论是否指定AM。当小时值等于0时不能指 定PM。 y 如果未指定AM和PM,小时值1~11表示中午以前的小时。当指定AM时,也表示中 午以前的小时。当指定PM时,则表示中午以后的小时。 y 如果未指定AM和PM,小时值12表示始于中午的小时。如果指定为AM,则表示始 于午夜的小时。如果指定为PM,则表示始于中午的小时。例如:12:01是指中午过 后1min,即12:01 PM,而12:01AM是指午夜过后1分钟。指定为12:01AM 与指定为 00:01或00:01 AM相同。 y 如果指定AM或PM,小时值为13~23表示中午以后的小时。当指定PM时,也表示 中午以后的小时。当小时值为13~23时,不能指定为AM。 y 小时值24无效,用12:00 AM或00:00表示午夜。 可以在毫秒之前加上冒号(:)或 者 句 号( .)。如果前面加冒号,这个数字表示1/1000s。 如果前面加句号,单个数字表示1/10s,两个数字表示1/100s,3个数字表示1/1000s。例如, 12:30:20:1表示12:30过了20又1/1000s;12:30:20.1表示12:30过了20又1/10s。 以下是使用日期时间数据类型的例子: CREATE TABLE Datetime_table ( c1 datetime, c2 smalldatetime, ) 135 第5章 Chapter 05 Transact-SQL及其程序设计基础 INSERT Datetime_table VALUES ('2001-05-15 00:04:39.257','04/15/1996 14:30:20 PM') SELECT * FROM Datetime_table 执行结果如下: c1 c2 --------------------------------------------- 2001-05-15 00:04:39.257 1996-04-15 14:30:00 (9)Unicode字符型 在SQL Server 2005中,传统上非Unicode数据类型允许使用由特定字符集定义的字符。 字符集是在安装SQL Server时选择的,不能更改。使用Unicode(统一字符编码标准)数据 类型,列(字段)可存储由Unicode标准定义的任何字符,包含由不同字符集定义的所有字 符。Unicode数据类型需要相当于非Unicode数据类型两倍的存储空间。 Unicode数据使用SQL Server中的nchar、varchar和ntext数据类型进行存储。对于存储来 源于多种字符集的字符的列,可采用这些数据类型。当列中各项所包含的Unicode字符数不 同时(至多为4000),使用nvarchar类型。当列中各项为同一固定长度时(至多为4000个 Unicode字 符 ),使 用 nchar 类型。当列中任意项超过4000个Unicode字符时,使用ntext类型, 其最大长度为230-1。它们分别和字符型的char[(n)]、varchar[(n)]和text类型相对应。 使用Unicode字符时,应该在前面加一个标识符N,但是存储时并不存储该标识符。例 如: DECLARE @MyUnicodeVar NCHAR(25) SET @MyUnicodeVar = N'This is a Unicode string.' PRINT @MyUnicodeVar 执行结果为: This is a Unicode string. (10)其他数据类型 在SQL Server 2005中,还提供了其他几种数据类型,包括下面几种: y cursor 游标数据类型,用于创建游标变量或者定义存储过程的输出参数。它是唯 一一种不能赋值给表的列(字段)的基本数据类型。 y sql_variant 该数据类型可以存储除了text、ntext、timestamp和自己本身以外的其 他所有类型的变量。 y table 该数据类型可以暂时存储应用程序的结果,以便在以后用到。 y timestamp 时间戳数据类型,它可以反映数据库中数据修改的相对顺序。 y uniqueidentifier 全局唯一标识符(Globally Unique Identification Numbers,GUID)。 它是一个16字节长的二进制数据类型,是SQL Server根据计算机网络适配器地址和 主机CPU时钟产生的唯一号码而生成的全局唯一标识符代码。唯一标识符代码可 以通过调用NEWID函数或者其他SQL Server应用程序编程接口来获得。 下面的示例使用NEWID对声明为uniqueidentifier数据类型的变量赋值,并将其打印出 来: 新概念 SQL Server 2005 教程 136 DECLARE @MyID uniqueidentifier SET @MyID = NEWID() PRINT 'Value of @MyID is: '+ CONVERT(varchar(255), @MyID) 执行结果为: Value of @MyID is: 42C285F5-620C-46D3-81A7-19A3C6113DBD 注 意 对于每台计算机,由NEWID返回的值不同。上面所显示的数字仅起解释的作用。另 外,CONVERT函数的作用是将一个数值转换为字符串。 2. 用户定义数据类型 用户定义的数据类型总是根据基本数据类型进行定义的。它们提供了一种机制,可以 将一个名称用于一个数据类型,这个名称更能清楚地说明该对象中保存的值的类型。这样 程序员和数据库管理员就能更容易地理解以该数据类型定义的对象的意图。 用户定义的数据类型使表结构对程序员更有意义,并有助于确保包含相似数据类的列 具有相同的基本数据类型。 提 示 用户定义数据类型基于SQL Server 2005中的系统数据类型。当多个表的列中要存储 同样类型的数据,且想确保这些列具有完全相同的数据类型、长度和为空性时,可使用用 户定义数据类型。例如,可以基于char数据类型创建名为postal_code的用户定义数据类型。 创建用户定义的数据类型时必须提供以下3个参数: y 名称; y 新数据类型所依据的系统数据类型; y 为空性(数据类型是否允许空值)。如果为空性未明确定义,系统将依据数据库 或连接的ANSI NULL默认设置进行指派。 如果用户定义数据类型是在model数据库中创建的,它将作用于所有用户定义的新数据 库中。如果数据类型在用户定义的数据库中创建,则该数据类型只作用于此用户定义的数 据库。 (1)通过SQL Server Management Studio来创建用户定义的数据类型 以在test数据库中创建用户定义数据类型为例,通过SQL Server Management Studio创建 用户定义的数据类型的操作步骤如下: 打开SQL Server Management Studio窗口,依次选择“数据库”| test |“可编程性” |“类型”选项。 在“用户定义数据类型”上右击鼠标,在打开的快捷菜单中,选择“新建用户定 义数据类型”命令,打开“新建用户定义数据类型”窗口,如图5.16所示。 137 第5章 Chapter 05 Transact-SQL及其程序设计基础 图 5.16 “新建用户定义数据类型”窗口 如“长度”处于活动状态,若要更改此数据类型可存储的最大数据长度,可输入 另外的值。长度可变的数据类型有binary、char、nchar、nvarchar、varbinary和varchar。若 要允许此数据类型接受空值,可选中“允许空值”复选框。 在“规则”和“默认值”文本框中单击 按钮选择一个规则或默认值(若有), 以将其绑定到用户定义数据类型上。 设置完成后,单击“确定”按钮,即可创建一个用户定义数据类型。 若要删除用户定义数据类型,可在该用户定义数据类型上右击鼠标,然后选择“删除” 命令,在打开的“除去对象”对话框中,单击“全部除去”按钮,即可删除用户定义数据 类型。 (2)使用存储过程 可以使用存储过程sp_addtype来创建用户定义数据类型,其语法格式为: sp_addtype [ @typename = ] type, [ @phystype = ] system_data_type [ , [ @nulltype = ] 'null_type' ] [ , [ @owner = ] 'owner_name' ] 各参数含义如下: y [@typename =] type 用户定义的数据类型的名称。数据类型名称必须遵循标识符 的规则,而且在每个数据库中必须是唯一的。type的数据类型为sysname,没有默 输入用户定义数据类型的名称。 选择基本数 据类型。 新概念 SQL Server 2005 教程 138 认值。 y [@phystype =] system_data_type 是用户定义的数据类型所基于的物理数据类型 或系统数据类型。 y [@nulltype =] 'null_type' 指明用户定义的数据类型处理空值的方式。null_type的数 据类型为varchar(8),默认值为NULL,并且必须用单引号引起来('NULL'、'NOT NULL' 或 'NONULL')。如果没有用sp_addtype显式定义null_type,则将其设置为 当前默认的(为空)。 y [@owner =] 'owner_name' 指定新数据类型的创建者或所有者。owner_name的数 据类型为sysname。当没有指定时,owner_name为当前用户。 该存储过程返回0表示成功,返回1表示失败。 提 示 sysname是一个系统支持的用户定义数据类型,等同于nvarchar(128),用来表示数据 库对象名。另外,用户定义的数据类型名称在数据库中必须是唯一的,但是名称不同的用 户定义的数据类型可以有相同的定义。 下面的示例为国内及国际电话和传真号码创建两个用户定义的数据类型telephone和 fax: EXEC sp_addtype telephone, 'varchar(24)', 'NOT NULL' EXEC sp_addtype fax, 'varchar(24)', 'NULL' 执行后,提示信息如下: 命令已成功完成。 表示已经成功执行,并生成两个用户定义数据类型。 删除用户定义数据类型可以使用sp_droptype存储过程,其语法为: sp_droptype [ @typename = ] 'type' 其中type表示要删除的用户定义数据类型的名称。 5.3.3 运算符 运算符是一种符号,用来指定要在一个或多个表达式中执行的操作。SQL Server提供 的运算符有算术运算符、赋值运算符、按位运算符、比较运算符、逻辑运算符、字符串连 接运算符和一元运算符。 1. 算术运算符 算术运算符在两个表达式上执行数学运算,这两个表达式可以是数字数据类型分类的 任何数据类型。在SQL Server中,算术运算符包括+(加)、-(减)、*(乘)、/(除)和 %(取模)。 取模运算返回一个除法的整数余数。例如,16%3=1,这是因为16除以3,余数为1。 139 第5章 Chapter 05 Transact-SQL及其程序设计基础 提 示 加(+)和减(–)运算符也可用于对datetime及smalldatetime值执行算术运算。 2. 赋值运算符 Transact-SQL有一个赋值运算符,即等号(=)。它将表达式的值赋予另外一个变量。 例如,下面的SQL语句先声明一个变量,然后将一个取模运算的结果赋予该变量,最后是 打印该变量的值: DECLARE @MyCounter INT SET @MyCounter = 17%3 PRINT CONVERT(varchar(255), @MyCounter) 执行结果为: 2 也可以使用赋值运算符在列标题和为列定义值的表达式之间建立关系。例如,下面的 SQL语句是将bookdb数据库中的book表的book_id均以“书籍”显示: USE bookdb SELECT book_id = '书籍',book_name,price FROM book 执行结果如下: book_id book_name price --------------------------------------------------------- 书籍 Windows Vista看图速成 30 书籍 3D Studio MAX实例精选 35 书籍 Windows 2003 Server网络管理 45 书籍 Mathematica 5.0入门与提高 30 3. 按位运算符 按位运算符可以对两个表达式进行位操作,这两个表达式可以是整型数据或者二进制 数据。按位运算符包括&(按位与)、|(按位或)和^(按位异或)。 Transact-SQL首先把整数数据转换为二进制数据,然后再对二进制数据进行按位运算。 例如,下面的SQL语句对两个变量进行按位运算: DECLARE @a INT,@b INT SET @a = 5 SET @b = 10 SELECT @a&@b,@a|@b,@a^@b 执行结果为: 0 15 15 按位运算的两个操作数不能同时是二进制字符串数据类型分类中的某种数据类型。 SQL Server所支持的操作数数据类型如表5.5所示。 新概念 SQL Server 2005 教程 140 表5.5 对按位远算的两个操作数的要求 左边操作数 右边操作数 Binary int、smallint 或 tinyint Bit int、smallint、tinyint 或 bit Int int、smallint、tinyint、binary 或 varbinary Smallint int、smallint、tinyint、binary 或 varbinary Tinyint int、smallint、tinyint、binary 或 varbinary Varbinary int、smallint 或 tinyint 注 意 按位运算符的两个操作数不能为image数据类型。 4. 比较运算符 比较运算符用来比较两个表达式,表达式可以是字符、数字或日期数据,并可用在查 询的WHERE或HAVING子句中。比较运算符的计算结果为布尔数据类型,它们根据测试条 件的输出结果返回TRUE或FALSE。 SQL Server提供的比较运算符有下面几种: y >(大于) y <(小于) y =(等于) y <=(小于或等于) y >=(大于或等于) y !=(不等于) y <>(不等于) y !<(不小于) y !>(不大于) 下面的SQL语句查询book表中价格大于35.0的书籍信息: USE bookdb SELECT * FROM book WHERE price > 35.0 执行结果如下: book_id author_id book_name price publisher 简介 ---------------------------------------------------------------------- 3 1 Windows 2003 Server网络管理 45.0 唐唐出版社 NULL 5. 逻辑运算符 逻辑运算符用来判断条件是为TRUE或者FALSE,SQL Server总共提供了10个逻辑运算 符,如表5.6所示。 141 第5章 Chapter 05 Transact-SQL及其程序设计基础 表5.6 逻辑运算符 逻辑运算符 含义 ALL 当一组比较关系的值都为 TRUE 时,才返回 TRUE AND 当要比较的两个布尔表达式的值都为 TRUE,才返回 TRUE ANY 只要一组比较关系中有一个值为 TRUE,就返回 TRUE BETWEEN 只有操作数在定义的范围内,才返回 TRUE EXISTS 如果在子查询中存在,就返回 TRUE IN 如果操作数在所给的列表表达式中,则返回 TRUE LIKE 如果操作数与模式相匹配,则返回 TRUE NOT 对所有其他的布尔运算取反 OR 只要比较的两个表达式有一个为 TRUE,就返回 TRUE SOME 如果一组比较关系中有一些为 TRUE,则返回 TRUE 例如,下面的SQL语句在book表中查询书名包含《网络管理》,而且价格在20~50之间 的书籍的信息: SELECT * FROM book WHERE (book_name LIKE '%网络管理%') AND (price BETWEEN 20 AND 50) 执行结果如下: book_id author_id book_name price publisher 简介 ---------------------------------------------------------------------- 3 1 Windows 2003 Server网络管理 45 唐唐出版社 NULL 由于LIKE使用部分字符串来寻找记录,因此,在部分字符串中可以使用通配符。例如 上面使用的%。可以使用的通配符及其含义如表5.7所示。 表5.7 通配符及其含义 通配符 含义 示例 % 包含零个或更多字符的任意字 符串 WHERE book_name LIKE '%computer%' 将查找处 于书名任意位置的包含单词computer的所有书名 _(下划线) 任何单个字符 WHERE author_name LIKE '刘__' 将查找姓刘的名 字包含3个字的作者(如刘耀儒等) [ ] 指定范围([a-f])或集合 ([abcdef])中的任何单个字符 WHERE author_name LIKE '[刘,王]__' 将查找姓刘 的和姓王的名字包含3个字的作者(如刘耀儒、王晓 明等) [^] 不属于指定范围([a-f])或 集 合 ([abcdef])的任何单个字符 WHERE author_name LIKE '[^刘,王]__' 将查找除姓 刘的和姓王的名字包含3个字的作者以外的其他作者 (如将查找除了刘耀儒、王晓明等的其他作者) 新概念 SQL Server 2005 教程 142 提 示 在使用通配符时,对于汉字,一个汉字也算一个字符。另外,当使用LIKE进行字符 串比较时,模式字符串中的所有字符都有意义,包括起始或尾随空格。如果查询中的比较 要返回包含“abc ”(abc后有一个空格)的所有行,则将不会返回包含“abc”(abc后没有 空格)的所有行。因此,对于datetime数据类型的值,应当使用LIKE进行查询,因为datetime 项可能包含各种日期部分。 6. 字符串连接运算符 字符串连接运算符为加号(+)。可以将两个或多个字符串合并或连接成一个字符串。 还可以连接二进制字符串。 例如,下面的SQL语句将两个字符串连接在一起: SELECT ('abc' + 'def') 执行结果如下: abcdef 其他数据类型,如datetime和smalldatetime,在与字符串连接之前必须使用CAST转换函 数将其转换成字符串。 7. 一元运算符 一元运算符是指只有一个操作数的运算符。SQL Server提供的一元操作符包含+(正)、 -(负)和~(位反)。 正和负运算符表示数据的正和负,可以对所有的数据类型进行操作。位反运算符返回 一个数的补数,只能对整数数据进行操作。 例如,下面的SQL语句,首先声明一个变量,并对变量赋值,然后对变量取负: DECLARE @Num1 int SET @Num1 = 5 SELECT -@Num1 执行结果如下: -5 8. 运算符优先级 当一个复杂的表达式有多个运算符时,运算符优先性决定执行运算的先后次序。执行 的顺序可能严重地影响所得到的值。 在SQL Server中,运算符的优先级如下: y +(正)、-(负)、~(按位NOT) y *(乘)、/(除)、%(模) y +(加)、+(连接)、-(减) y =、>、<、>=、<=、<>、!=、!>和!<比较运算符 143 第5章 Chapter 05 Transact-SQL及其程序设计基础 y ^(位异或)、&(位与)、|(位或) y NOT y AND y ALL、ANY、BETWEEN、IN、LIKE、OR、SOME y =(赋值) 当一个表达式中的两个运算符有相同的运算符优先级时,基于它们在表达式中的位置 来对其从左到右进行求值。例如,在下面的示例中,在SET语句中使用的表达式中,在加 号运算符之前先对减号运算符进行求值: DECLARE @MyNumber int SET @MyNumber = 6 - 5 + 7 SELECT @MyNumber 执行结果为: 8 使用括号可以提高运算符的优先级,首先对括号中的内容进行求值,从而产生一个值, 然后括号外的运算符才可以使用这个值。如果有嵌套的括号,则处于最里面的括号最先计 算。例如: DECLARE @MyNumber int SET @MyNumber = 3 * (5 + (7 - 3) ) SELECT @MyNumber 执行结果为: 27 5.3.4 变量 在SQL Server中,变量分为局部变量和全局变量。全局变量名称前面有两个@字符, 由系统定义和维护。局部变量前面有一个@字符,由用户定义和使用。 1. 局部变量 局部变量由用户定义,仅在声明它的批处理、存储过程或者触发器中有效。批处理结 束后,局部变量将变成无效。 局部的定义可以使用DECLARE语句,其语法格式如下: DECLARE { @local_variable data_type }[,…n] 各参数含义如下: y @local_variable 是变量的名称。变量名必须以at符(@)开头。局部变量名必须 符合标识符规则。 y data_type 是任何由系统提供的或用户定义的数据类型。变量不能是text、ntext或 image数据类型。 新概念 SQL Server 2005 教程 144 在SQL Server中,一次可以定义多个变量。例如: DECLARE @maxprice float,@pub char(12) 如果要给变量赋值,可以使用SET和SELECT语句。其语法格式如下: SET @local_variable =expression SELECT { @local_variable =expression}[,…n] 其中@local_variable为定义的局部变量名称,expression为一表达式。 例如,下面首先定义了两个变量,并分别使用SET和SELECT为其赋值,然后使用这两 个变量查询价格小于50且出版社为“明耀工作室”的书籍信息: DECLARE @maxprice float,@pub char(12) SET @maxprice =50 SELECT @pub='明耀工作室' SELECT * FROM book WHERE price < @maxprice AND publisher = @pub 执行结果如下: book_id author_id book_name price publisher 简介 ---------------------------------------------------------------------- 1 1 Windows Vista看图速成 30 明耀工作室 NULL 2 2 3D Studio MAX实例精选 35 明耀工作室 NULL 提 示 SELECT @local_variable通常用于将单个值返回到变量中。例如,如果expression为列 名,则返回多个值。如果SELECT语句返回多个值,则将返回的最后一个值赋予变量。如 果SELECT语句没有返回行,变量将保留当前值。如果expression是不返回值的标量子查询, 则将变量设为 NULL。一般来说,应该使用SET,而不是SELECT给变量赋值。 2. 全局变量 全局变量记录了SQL Server的各种状态信息,它们不能被显式地赋值或声明,而且不 能由用户定义。在SQL Server 2005中,定义了全局变量,如表5.8所示。 表5.8 SQL Server 2005中的全局变量 变量名称 说明 @@CONNECTIONS 返回自SQL Server本次启动以来,所接受的连接或试图连接的次数 @@CPU_BUSY 返回自SQL Server本次启动以来,CPU工作的时间,单位为毫秒(ms) @@CURSOR ROWS 返回游标打开后,游标中的行数 @@DATEFIRST 返回SET DATAFIRST参数的当前值 @@DBTS 返回当前数据库的当前timestamp数据类型的值 @@ERROR 返回上次执行的SQL Transact语句产生的错误数 @@FETCH_STATUS 返回FETCH语句游标的状态 @@IDENTITY 返回最新插入的IDENTITY列值 @@IDLE 返回自SQL Server本次启动以来,CPU空闲的时间,单位为毫秒 145 第5章 Chapter 05 Transact-SQL及其程序设计基础 (续表) 变量名称 说明 @@IO_BUSY 返回自SQL Server本次启动以来,CPU处理输入和输出操作的时间,单 位为毫秒 @@LANGID 返回本地当前使用的语言标识符 @@LANGUAGE 返回当前使用的语言名称 @@LOCK_TIMEOUT 返回当前的锁定超时设置,单位为毫秒 @@MAX_CONNECTIONS 返回SQL Server允许同时连接的最大用户数目 @@MAX_PRECISION 返回当前服务器设置的decimal和numeric数据类型使用的精度 @@NESTLEVEL 返回当前存储过程的嵌套层数 @@OPTIONS 返回当前SET选项信息 @@PACK RECEIVED 返回自SQL Server本次启动以来,通过网络读取的输入数据包数目 @@PACK SENT 返回自SQL Server本次启动以来,通过网络发送的输出数据包数目 @@PACKET ERRORS 返回自SQL Server本次启动以来,SQL Server中出现的网络数据包的错 误数目 @@PROCID 返回当前的存储过程标识符 @@REMSERVER 返回注册记录中显示的远程数据服务器的名称 @@ROWCOUNT 返回上一个语句所处理的行数 @@SERVERNAME 返回运行SQL Server的本地服务器名称 @@SERVICENAME 返回SQL Server运行时的注册键名称 @@SPID 返回服务器处理标识符 @@TEXTSIZE 返回当前TESTSIZE选项的设置值 @@TIMETICKS 返回一个计时单位的微秒数,操作系统的一个计时单位是31.25ms @@TOTAL ERRORS 返回自SQL Server本次启动以来,磁盘的读写错误次数 @@TOTAL READ 返回自SQL Server本次启动以来,读磁盘的次数 @@TOTAL WRITE 返回自SQL Server本次启动以来,写磁盘的次数 @@TRANCOUNT 返回当前连接的有效事务数 @@VERSION 返回当前SQL Server服务器的日期,版本和处理器类型 5.3.5 批处理 批处理是包含一个或多个Transact-SQL语句的组,从应用程序一次性地发送到SQL Server执行。SQL Server将批处理语句编译成一个可执行单元,此单元称为执行计划。执行 计划中的语句每次执行一条。一个批处理语句以GO结束。 编译错误(如语法错误)使执行计划无法编译,从而导致批处理中的任何语句均无法 执行。 运行时错误(如算术溢出或违反约束)会产生以下两种影响之一: y 大多数运行时错误将停止执行批处理中当前语句和它之后的语句。 y 少数运行时错误(如违反约束)仅停止执行当前语句。而继续执行批处理中其他 新概念 SQL Server 2005 教程 146 所有语句。 在遇到运行时错误之前执行的语句不受影响。唯一的例外是,如果批处理在事务中, 而且错误导致事务回滚。在这种情况下,回滚运行时错误之前所进行的未提交的数据修改。 假定在批处理中有10条语句。如果第5条语句有一个语法错误,则不执行批处理中的任 何语句。如果编译了批处理,而第2条语句在执行时失败,则第1条语句的结果不受影响, 因为它已经执行。 在建立一个批处理的时候,应该注意下面的规则: y CREATE DEFAULT 、 CREATE PROCEDURE 、 CREATE RULE 、 CREATE TRIGGER和CREATE VIEW语句不能在批处理中与其他语句组合使用。批处理必 须以CREATE语句开始。所有跟在该批处理后的其他语句将被解释为第一个 CREATE语句定义的一部分。 y 不能在同一个批处理中更改表,然后引用新列。 y 如果EXECUTE语句是批处理中的第一句,则不需要EXECUTE关键字。如果 EXECUTE语句不是批处理中的第一条语句,则需要EXECUTE关键字。 下面的SQL语句创建一个视图。因为CREATE VIEW必须是批处理中的唯一语句,所 以需要GO命令将CREATE VIEW语句与其周围的USE和SELECT语句隔离: USE bookdb GO CREATE VIEW auth_titles AS SELECT * FROM authors GO SELECT * FROM auth_titles GO 执行结果如下: author_id author_name adrress telephone --------------------------------------------------------------- 1 刘耀儒 北京市海淀区 010-66886688 2 王晓明 北京市东城区 010-66888888 3 张英魁 NULL NULL 5.3.6 注释 注释是指程序代码中不执行的文本字符串,也称为注解。使用注释对代码进行说明, 可使程序代码更易于维护。注释通常用于记录程序名称、作者姓名和主要代码更改的日期。 注释可用于描述复杂计算或解释编程方法。 SQL Server支持两种类型的注释字符: y --(双连字符) 这些注释字符可与要执行的代码处在同一行,也可另起一行。从 双连字符开始到行尾均为注释。对于多行注释,必须在每个注释行的开始使用双 连字符。 y /*…*/(正斜杠-星号对) 这些注释字符可与要执行的代码处在同一行,也可另 147 第5章 Chapter 05 Transact-SQL及其程序设计基础 起一行,甚至在可执行代码内。从开始注释对(/*)到结束注释对(*/)之间的全 部内容均视为注释部分。对于多行注释,必须使用开始注释字符对(/*)开始注释, 使用结束注释字符对(*/)结束注释。注释行上不应出现其他注释字符。 下面就是使用注释的例子: USE bookdb GO --这是双连字符注释 SELECT * FROM book --从表book中查询书籍信息 GO /*这是正斜杠-星号对 注释*/ SELECT * FROM authors /*查询作者信息*/ GO 注 意 多行“/*…*/”注释不能跨越批处理。整个注释必须包含在一个批处理内。 5.3.7 控制流语句 Transact-SQL提供称为控制流的特殊关键字,用于控制Transact-SQL语句、语句块和存 储过程的执行流。这些关键字可用于Transact-SQL语句、批处理和存储过程中。 控制流语句就是用来控制程序执行流程的语句,使用控制流语句可以在程序中组织语 句的执行流程,提高编程语言的处理能力。SQL Server提供的控制流语句如表5.9所示。 表5.9 控制流语句 控制流语句 说明 BEGIN…END 定义语句块 GOTO 无条件跳转语句 CASE 分支语句 IF…ELSE 条件处理语句,如果条件成立,执行 IF 语句;否则执行 ELSE 语句 RETURN 无条件退出语句 WAITFOR 延迟语句 WHILE 循环语句 BREAK 跳出循环语句 CONTINUE 重新开始循环语句 1. BEGIN…END 语句 BEGIN…END语句用于将多个Transact-SQL语句组合为一个逻辑块。在执行时,该逻 辑块作为一个整体被执行。 BEGIN…END语句用于将多个Transact-SQL语句组合为一个逻辑块。在执行时,该逻 辑块作为一个整体被执行。其程序代码段如下: 新概念 SQL Server 2005 教程 148 BEGIN { sql_statement | statement_block} END 其中{sql_statement|statement_block}是任何有效的Transact-SQL语句或以语句块定义的 语句分组。 任何时候当控制流语句必须执行一个包含两条或两条以上Transact-SQL语句的语句块 时,都可以使用BEGIN和END语句。它们必须成对使用,任何一条语句均不能单独使用。 BEGIN语句行后为Transact-SQL语句块。最后,END语句行指示语句块结束。 BEGIN…END语句可以嵌套使用。例如: BEGIN DECLARE @MyVar float SET @MyVar = 456.256 BEGIN PRINT '变量@MyVar的值为:' PRINT CAST(@MyVar AS varchar(12)) END END 执行结果为: 变量@MyVar的值为: 456.256 下面几种情况经常要用到BEGIN和END语句: y WHILE循环需要包含语句块。 y CASE函数的元素需要包含语句块。 y IF或ELSE子句需要包含语句块。 注 意 上述情况下,如果只有一条语句,则不需要使用BEGIN…END语句。 2. IF…ELSE 语句 使用IF…ELSE语句,可以有条件地执行语句。其语法格式如下: IF Boolean_expression {sql_statement | statement_block} [ELSE {sql_statement | statement_block}] 各参数含义如下: y Boolean_expression 布尔表达式,可以返回TRUE或FALSE。如果布尔表达式中含 有SELECT语句,必须用圆括号将SELECT语句括起来。 y {sql_statement | statement_block} Transact-SQL语句或用语句块定义的语句分组。 除非使用语句块,否则IF或ELSE条件只能影响一个Transact-SQL语句的性能。若 149 第5章 Chapter 05 Transact-SQL及其程序设计基础 要定义语句块,可以使用控制流关键字BEGIN…END。 IF…ELSE语句的执行方式是:如果布尔表达式的值为TRUE,则执行IF后面的语句块; 否则执行ELSE后面的语句块。 例如: USE bookdb IF (SELECT price FROM book WHERE book_name LIKE '%网络管理%')>50 BEGIN PRINT '这本书太贵了!' PRINT '我承受不起!' END ELSE BEGIN PRINT '这本书还可以!' PRINT '我要买一本!' END 执行结果为: 这本书还可以! 我要买一本! 在IF…ELSE语句中,IF和ELSE后面的子句都允许嵌套,嵌套层数不受限制。 注 意 如果在IF…ELSE语句的IF区和ELSE区都使用了CREATE TABL语句或 SELECT INTO语句,那么CREATE TABLE语句或SELECT INTO语句必须指向相同的表名。 3. CASE 语句 使用CASE语句可以进行多个分支的选择。CASE具有两种格式: y 简单CASE格式 将某个表达式与一组简单表达式进行比较以确定结果。 y 搜索CASE格式 计算一组布尔表达式以确定结果。 简单CASE格式语法格式为: CASE input_expression WHEN when_expression THEN result_expression […n ] [ ELSE else_result_expression ] END 其中各参数的含义如下: y input_expression 使用简单CASE格式时所计算的表达式,可以是任何有效的表达 式。 y when_expression 用来和Input_expression做比较的表达式。Input_expression和每个 when_expression的数据类型必须相同或者是隐性转换。 新概念 SQL Server 2005 教程 150 y result_expression 当input_expression = when_expression的取值为TRUE时,需要返 回的表达式。 y else_result_expression 当input_expression = when_expression的取值为FALSE时, 需要返回的表达式。 简单CASE格式的执行方式为:当input_expression = when_expression的取值为TRUE, 则返回result_expression;否则返回else_result_expression。如果没有ELSE子句,则返回NULL。 例如: USE pubs GO SELECT au_fname, au_lname, CASE state WHEN 'CA' THEN 'California' WHEN 'KS' THEN 'Kansas' WHEN 'TN' THEN 'Tennessee' WHEN 'OR' THEN 'Oregon' WHEN 'MI' THEN 'Michigan' WHEN 'IN' THEN 'Indiana' WHEN 'MD' THEN 'Maryland' WHEN 'UT' THEN 'Utah' END AS StateName FROM pubs.dbo.authors WHERE au_fname LIKE 'M%' 执行结果如下: au_fname au_lname StateName ------------------------------------- Marjorie Green California Michael O'Leary California Meander Smith Kansas Morningstar Greene Tennessee Michel DeFrance Indiana 搜索CASE格式语法格式为: CASE WHEN Boolean_expression THEN result_expression […n ] [ ELSE else_result_expression END 搜索CASE格式的执行方式为:如果Boolean_expressio表达式的值为TRUE,则返回 THEN后面的表达式result_expression,然后跳出CASE语句;否则继续测试下一个WHEN后 面的布尔表达式。如果所有的WHEN后面的布尔表达式均为FALSE,则返回ELSE后面的表 达式。没有ELSE子句时,返回NULL。 例如: USE bookdb GO 151 第5章 Chapter 05 Transact-SQL及其程序设计基础 SELECT book_name, CASE WHEN price>=50 THEN '太贵了!' WHEN price>=40 THEN '还可以,考虑考虑!' ELSE '挺便宜的,买一本' END AS 价格 FROM book GO 执行结果如下: book_name 价格 -------------------------------------------------------------- Windows Vista看图速成 挺便宜的,买一本 3D Studio MAX实例精选 挺便宜的,买一本 Windows 2003 Server网络管理 还可以,考虑考虑! Mathematica 5.0入门与提高 挺便宜的,买一本 4. WHILE 语句 WHILE语句可以设置重复执行SQL语句或语句块的条件。只要指定的条件为真,就重 复执行语句。可以使用BREAK和CONTINUE关键字在循环内部控制WHILE循环中语句的 执行。 其语法格式如下: WHILE Boolean_expression { sql_statement | statement_block } [ BREAK ] { sql_statement | statement_block } [ CONTINUE ] 各参数含义如下: y Boolean_expression 返回TRUE或FALSE的布尔表达式。如果布尔表达式中含有 SELECT语句,必须用圆括号将SELECT语句括起来。 y {sql_statement | statement_block} Transact-SQL语句或用语句块定义的语句分组。 若要定义语句块,可以使用BEGIN…END语句。 y BREAK 导致从最内层的WHILE循环中退出。将执行出现在END关键字后面的任 何语句,END关键字为循环结束标记。 y CONTINUE 使WHILE循环重新开始执行,忽略CONTINUE关键字后的任何语 句。 WHILE语句的执行方式为:如果布尔表达式的值为TRUE,则反复执行WHILE语句后 面的语句块;否则将跳过后面的语句块。 例如,下面的SQL语句是计算从1加到100的值: DECLARE @MyResult int,@MyVar int SET @MyVar = 0 SET @MyResult = 0 WHILE @MyVar<=100 新概念 SQL Server 2005 教程 152 BEGIN SET @MyResult = @MyResult+@MyVar SET @MyVar=@MyVar+1 END PRINT CAST(@MyResult AS char(25)) 执行结果为: 5050 5. GOTO 语句 GOTO语句可以实现无条件的跳转。其语法格式为: GOTO lable 其中lable为要跳转到的语句标号。其名称要符合标识符的规定。 GOTO语句的执行方式为:遇到GOTO语句后,直接跳转到lable标号处继续执行,而 GOTO后面的语句将不被执行。 例如,使用下面的语句重新计算从1加到100的值: DECLARE @MyResult int,@MyVar int SET @MyVar = 0 SET @MyResult = 0 my_loop: --定义标号 SET @MyResult = @MyResult+@MyVar SET @MyVar=@MyVar+1 IF @MyVar<=100 GOTO my_loop --如果小于100,跳转到my_loop标号处 PRINT CAST(@MyResult AS char(25)) 执行结果与上面相同。 6. RETURN 语句 使用RETURN语句,可以从查询或过程中无条件退出。可在任何时候用于从过程、批 处理或语句块中退出,而不执行位于RETURN之后的语句。 语法格式为: RETURN [ integer_expression ] 其中integer_expression为一整数数值,是RETURN语句要返回的值。 注 意 当用于存储过程时,RETURN不能返回空值。如果试图返回空值,将生成警告信息 并返回0值。 例如,首先执行下面的SQL语句创建一个存储过程: USE bookdb GO CREATE PROC MyPro @bookname char(50) --创建存储过程MyPro AS 153 第5章 Chapter 05 Transact-SQL及其程序设计基础 IF (SELECT price FROM book WHERE book_name LIKE @bookname)>=50 RETURN 1 ELSE RETURN 2 然后执行下面的SQL语句: DECLARE @Return_value int EXEC @Return_value=MyPro '%网络管理%' IF @Return_value=1 PRINT '这本书太贵了!' ELSE PRINT '这本书还可以,值得考虑购买!' GO 执行结果如下: 这本书还可以,值得考虑购买! 提 示 关于存储过程的详细信息,可参考第9章。 7. WAITFOR 语句 使用WAITFOR语句,可以在指定的时间或者过了一定时间后,执行语句块、存储过程 或者事务。 其语法格式为: WAITFOR { DELAY 'time' | TIME 'time' } y DELAY 指示SQL Server一直等到指定的时间过去,最长可达24h。 y 'time' 要等待的时间。可以按datetime数据可接受的格式指定time,也可以用局部 变量指定此参数。不能指定日期,因此在datetime值中不允许有日期部分。 y TIME 指示SQL Server等待到指定时间。 例如,下面的SQL语句指定在1:58:00时执行一个语句: BEGIN WAITFOR TIME '1:58:00' PRINT '现在是1:58:00' END 执行后,等计算机上的时间到了1:58:00时,出现下面结果: 现在是1:58:00 5.3.8 函数 编程语言中的函数是用于封装经常执行的逻辑的子例程。任何代码若必须执行函数所 包含的逻辑,都可以调用该函数,而不必重复所有的函数逻辑。SQL Server 2005支持两种 函数类型:内置函数和用户定义函数。 新概念 SQL Server 2005 教程 154 1. 内置函数 SQL Server 2005提供了丰富的具有执行某些运算功能的内置函数,可分为12类,如表 5.10所示。 使用函数时总是带有圆括号,即使没有参数也是如此。例外情况是与DEFAULT关键字 一起使用的niladic函数(不带参数的函数)。而且函数可以嵌套(一个函数用于另一个函 数内部)。 例如,下面是一个使用内置函数的例子: PRINT '现在日期和时间是:' + CAST(GETDATE() AS char(50)) 执行结果如下: 现在日期和时间是: 9 2007 2:34PM 有时,用来指定数据库、计算机、登录或数据库用户的参数是可选的。如果未指定这 些参数,就默认地将这些参数赋值为当前的数据库、主机、登录或数据库用户。 函数可以是确定性的,也可以是非确定性的,如表5.10所示。如果任何时候使用特定 的输入值集调用函数时总是返回相同的结果,则称该函数为确定性函数。如果每次使用特 定的输入值集调用函数时返回不同的结果,则该函数是非确定性函数。 表5.10 SQL Server 2005提供的内置函数 函数分类 说明 聚合函数 执行的操作是将多个值合并为一个值,例如COUNT、SUM、MIN和MAX 配置函数 是一种标量函数,可返回有关配置设置的信息 游标函数 返回有关游标状态的信息 日期和时间函数 操作datetime和smalldatetime值 数学函数 执行三角、几何和其他数字运算 元数据函数 返回数据库和数据库对象的特性信息 行集函数 返回行集,这些行集可用在Transact-SQL语句中表引用所在的位置 安全性函数 返回有关用户和角色的信息 字符串函数 操作char、varchar、nchar、nvarchar、binary和varbinary值 系统函数 对系统级别的各种选项和对象进行操作或报告 系统统计函数 返回有关SQL Server性能的信息 文本和图像函数 操作text和image值 2. 用户定义函数 函数是由一个或多个Transact-SQL语句组成的子程序,可用于封装代码以便重新使用。 SQL Server 2005并不将用户限制在定义为Transact-SQL语言一部分的内置函数上,而是允许 用户创建自己的用户定义函数。 可使用CREATE FUNCTION语句创建,使用ALTER FUNCTION语句修改,以及使用 DROP FUNCTION 语句除去用户定义函数。每个完全合法的用户定义函数名 155 第5章 Chapter 05 Transact-SQL及其程序设计基础 (database_name.owner_name.function_name)必须唯一。 SQL Server 2005支持3种用户定义函数: y 标量函数; y 内嵌表值函数; y 多语句表值函数。 注 意 在用户定义函数中,BEGIN…END块中的语句不能有任何副作用。函数副作用是指 对具有函数外作用域(例如数据库表的修改)的资源状态的任何永久性更改。函数中的语 句唯一能做的更改是对函数上的局部对象(如局部游标或局部变量)的更改。不能在函数 中执行的操作包括:对数据库表的修改,对不在函数上的局部游标进行操作,发送电子邮 件,尝试修改目录,以及生成返回至用户的结果集。 用户定义函数接受零个或更多的输入参数,并返回单值。函数最多可以有1024个输入 参数。 例如:下面的SQL语句在test数据库中定义了一个CubicVolume用户定义函数,然后使 用该函数计算一个长方体的体积: USE test GO CREATE FUNCTION CubicVolume --输入参数 (@CubeLength decimal(4,1), @CubeWidth decimal(4,1), @CubeHeight decimal(4,1) ) RETURNS decimal(12,3) -- 返回立方体的体积 AS BEGIN RETURN ( @CubeLength * @CubeWidth * @CubeHeight ) END GO PRINT CAST(dbo.CubicVolume(20,5, 10) AS char(255)) GO 执行结果为: 1000.000 SQL Server 2005还支持返回table数据类型的用户定义函数: y 该函数可声明内部table变量,将行插入该变量,然后将该变量作为返回值返回。 y 一类称为内嵌函数的用户定义函数,将SELECT语句的结果集作为变量类型table 返回。 这些函数可用在能指定表达式的地方。返回table的用户定义函数可以是替代视图的强 大方式。返回table的用户定义函数可用在Transact-SQL查询中允许表或视图表达式的地方。 新概念 SQL Server 2005 教程 156 视图受限于单个SELECT语句,而用户定义函数可包含附加的语句,使函数所包含的逻辑 比视图可能具有的逻辑更强大。 返回table的用户定义函数还可替换返回单个结果集的存储过程。由用户定义函数返回 的table可在Transact-SQL语句的FROM子句中引用,而返回结果集的存储过程则不能。 例如: USE bookdb GO CREATE FUNCTION SearchBook ( @BookPrice float ) RETURNS @BookInfo TABLE ( book_name char(50), author_name char(8), book_price float, publisher char(50) ) AS BEGIN INSERT @BookInfo SELECT book.book_name,authors.author_name,book.price,book.publisher FROM book,authors WHERE book.author_id = authors.author_id AND book.price > @BookPrice RETURN END GO 在这个函数中,返回的本地变量名是@BookInfo。函数中的语句在@BookInfo变量中插入 行,以生成由该函数返回的table结果。外部语句唤醒调用该函数以引用由该函数返回的 table。下面的SQL语句即使用该函数查询价格大于35的书籍信息: SELECT * FROM SearchBook(35) 执行结果为: book_name author_name book_price publisher ---------------------- ------------ ---------- ---------- Windows 2003 Server网络管理 刘耀儒 45 唐唐出版社 5.4 课堂演练 5.4.1 在users表中插入记录 为了后面制作公告信息系统的需要,本节使用INSERT语句在users表中插入记录。操作 步骤如下: 打开SQL Server Management Studio窗口,在工具栏上单击“新建查询”按钮。 输入如下SQL语句: 157 第5章 Chapter 05 Transact-SQL及其程序设计基础 USE boarddb GO INSERT users(userID,password) VALUES('zhangsan',' zhangsan ') 单击“执行”按钮即可在users表中插入一个记录。可根据需要插入其他记录。 5.4.2 显示打折后的书籍价格 若要将所有书籍打9折出售,使用SQL语句查询打折后的书名和价格。可以使用下面的 SQL语句: USE bookdb GO SELECT book_name AS 书名,(price*0.9) AS 打折后的价格 FROM book 5.4.3 判断学生成绩及格与否 在test数据库中创建一个表score,包括字段student_no、student_name和student_score。 分别表示学号、学生姓名和学生成绩。编制一个函数,用于对给定的分数进行判断:大于 85,返回“优秀”;大于60,返回“通过”;小于60,则返回“不通过”。其SQL语句如 下: USE test GO SELECT student_no AS 学号, student_name AS 姓名, CASE WHEN student_score>=85 THEN '优秀' WHEN student_score>=60 THEN '通过' ELSE '不通过' END AS 通过与否 FROM score GO 5.5 小结 本章介绍了SQL查询分析器的使用、简单的Transact-SQL查询,并介绍了使用 Transact-SQL进行编程的基础知识。 SQL查询分析器是分析执行SQL语句并显示结果的图形化工具。可以执行SQL语句, 也可以将SQL语句保存为一个文本文件,然后一起执行。 SELECT语句是SQL语言的核心和重点,使用也最广泛,因此应熟练掌握。 与高级语言类似,Transact-SQL语言也存在变量、运算符、控制流语句、函数等概念, 但是由于它是和数据库紧密结合在一起的,因此在细节方面和高级语言有很大差别。其中 用户定义函数是SQL Server 2005新增的功能,因而用户能更方便地使用Transact-SQL语言 进行编程,扩展Transact-SQL语言的功能。 新概念 SQL Server 2005 教程 158 5.6 课后练习 5.6.1 简答题 (1)Trancat-SQL语言主要由哪几部分组成?各部分的功能是什么? (2)说明SELECT语句的基本用法。 5.6.2 操作题 (1)使用bookdb数据库,查询价格大于35的书籍的书名、作者、价格和出版社,在显 示时使用中文名字。 操作步骤提示: 这是一个带条件的多表查询。可以使用下面的语句: USE bookdb GO SELECT book_name AS 书名,author_name AS 作者,price AS 价格, publisher AS 出版社 FROM book,authors WHERE price > 35 (2)在test数据库中建立一个表,字段分别为col1和col2,均为整型,然后插入两笔记 录(随意),计算每笔记录中两个字段的乘积。最后显示所有记录及其乘积,使用SQL语 句完成上述功能。 第 6 章 提高检索效率的索引 06 Chapter 本章导读: ” 建立索引的原因 ” 建立索引应该考虑的问题 ” 聚集索引和非聚集索引 ” 索引的创建 ” 索引的查看 ” 索引的删除 ” 全文目录 ” 全文索引 6.1 索引简介 SQL Server的性能受许多因素的影响,因此有效地设计索引可以提高其性能。索引和 书的目录类似。如果把表的数据看作书的内容,则索引就是书的目录。书的目录指向了书 的内容(通过页码),同样,索引是表的关键值,它提供了指向表中行(记录)的指针。 目录中的页码是到达书内容的直接路径,而索引也是到达表数据的直接路径,从而可更高 效地访问数据。 可以利用索引快速访问数据库表中的特定信息。索引是对数据库表中一个或多个列的 值进行排序的结构。 索引提供指针以指向存储在表中指定列的数据值,然后根据指定的排序次序排列这些 指针。数据库使用索引的方式与使用书的目录很相似:通过搜索索引找到特定的值,然后 跟随指针到达包含该值的行。 在数据库关系图中,可以为选定的表创建、编辑或删除索引/键属性页中的每个索引类 型。当保存附加在此索引上的表或包含此表的数据库关系图时,索引同时被保存。 提 示 通常情况下,只有当经常查询索引列中的数据时,才需要在表上创建索引。索引将 占用磁盘空间,并且降低添加、删除和更新行的速度。不过在多数情况下,索引所带来的 数据检索速度的优势大大超过它的不足之处。然而,如果应用程序非常频繁地更新数据, 或磁盘空间有限,那么最好限制索引的数量。 新概念 SQL Server 2005 教程 160 6.1.1 创建索引的原因 索引是为了加速检索而创建的一种存储结构。索引是针对一个表而建立的。它是由除 存放表的数据页面以外的索引页面组成的。每个索引页面中的行都包含逻辑指针,通过该 指针可以直接检索到数据,这就会加速物理数据的检索。 对表中的列(字段)是否创建索引以及创建何种索引,对检索的速度会有很大的影响。 创建了索引的列几乎是立即响应,而未创建索引的列就需要等很长时间。因为对于未创建 索引的列,SQL Server需要逐行进行搜索,这种搜索耗费的时间直接同表中的数据量成正 比。当数据量很大时,耗费的时间是难以想象的。 索引有下述优点。 1. 提高查询速度 如果一个表上没有索引,在进行查询时,SQL Server就可能强制按照表的顺序逐行进 行搜索。为了查找满足条件的所有行,必须访问表的每一行。对于一个具有上万笔记录的 大型表来说,表的搜索可能要花费很长时间。 如果要查询的列上具有索引,则就不会花费太长时间。因为SQL Server首先搜索这个 索引,找到要查询的值,然后按照索引中的位置信息确定表中的行。由于索引进行了分类, 并且索引的行和列比较少,索引的搜索是很快的。 同样,通过索引删除行也是很快的,这是由于索引会告诉SQL Server在磁盘上行(记 录)的位置。 针对上面书的类比,可以这样想象,如果没有目录,查找书中的内容是很费时的。就像没 有索引一样,必须逐页进行查找。直到找到为止。如果有了目录,则结果就会大不相同。 2. 提高连接、ORDER BY(查询的结果排序)和 GROUP BY(查询的结果归类)执 行的速度 连接、ORDER BY(查询的结果排序)和GROUP BY(查询的结果归类)都需要对数 据进行检索,如果建立了索引,则连接、ORDER BY(查询的结果排序)和GROUP BY(查 询的结果归类)执行的速度就会大大提高。 3. 查询优化器依靠索引起作用 在执行查询时,SQL Server会自动对查询进行优化。但是SQL Server的优化是依靠索引 来进行的。因此,在建立索引后,SQL Server会依据建立的索引,决定采取哪些索引,使 得检索的速度最快。 4. 强制实施行的唯一性 创建唯一索引,可以保证表中的数据不重复。 总之,索引可以为性能带来好处,但是是有代价的。带索引的表在数据库中会占据更 多的空间。另外,为了维护索引,对数据进行插入、更新和删除等命令的操作所花费的时 间会更长。在设计和创建索引时,应确保对性能的提高程度大于在存储空间和处理资源方 面的代价。 161 第6章 Chapter 06 提高检索效率的索引 6.1.2 建立索引应该考虑的问题 当SQL Server 2005执行查询时,数据库引擎优化顾问会对可用的数据检索方法的成本 进行评估,从中选用最有效的方法。SQL Server可以扫描表,如果索引存在,则使用索引。 当SQL Server执行表扫描时,它从表的第一行开始逐行查找,将符合查询条件的行提取出 来。当SQL Server使用索引时,它会查找查询所需的行的存储位置,并只提取出所需的行。 在考虑是否为一个列创建索引时,应考虑被索引的列是否已经用于查询中以及如何用 于查询中。索引对下列查询是很有帮助的: y 搜索符合特定搜索关键字值的行(精确匹配查询)。精确匹配查询是指查询使用 WHERE语句指定具有给定值的列条目。例如:WHERE publisher='东东工作室'。 y 搜索其搜索关键字值为范围值的行(范围查询)。范围查询是指查询指定其值介 于两个值之间的任何条目。例如:WHERE price BETWEEN price 35 and 45。 y 根据联接谓词,在表T1中搜索与表T2中的某个行匹配的行(索引嵌套循环联接)。 y 在不进行显式排序操作情况下产生经排序的查询输出,尤其是经排序的动态游标。 y 在不进行显式排序操作的情况下,按一种有序的顺序对行进行扫描,以允许基于 顺序的操作,如合并联接和流聚合。 y 以优于表扫描的性能对表中所有的行进行扫描,性能提高是由于减少了要扫描的 列集和数据总量(该查询有覆盖索引可供使用)。 y 搜索插入和更新操作中重复的新搜索关键字值,以实施PRIMAR YKEY和UNIQUE 约束。 y 搜索已定义了FOREIGN KEY约束的两个表之间匹配的行。 提 示 使用LIKE比较进行查询时,如果模式以特定字符串如“abc%”开头,使用索引则会 提高效率;如果模式以通配符如“%xyz”开头,则索引不起作用。 创建索引应考虑的主要因素有: y 一个表如果建有大量索引会影响INSERT、UPDATE和DELETE语句的性能,因为 在表中的数据更改时,所有索引都须进行适当的调整。另一方面,对于不需要修 改数据的查询(SELECT语句),大量索引有助于提高性能,因为SQL Server有更 多的索引可供选择,以便确定以最快速度访问数据的最佳方法。 y 覆盖的查询可以提高性能。覆盖的查询是指查询中所有指定的列都包含在同一个 索引中。例如,如果在一个表的a、b和c列上创建了组合索引,则从该表中检索a 和b列的查询被视为覆盖的查询。创建覆盖一个查询的索引可以提高性能,因为该 查询的所有数据都包含在索引自身当中;检索数据时只需引用表的索引页,不必 引用数据页,因而减少了I/O总量。尽管给索引添加列以覆盖查询可以提高性能, 但在索引中额外维护更多的列会产生更新和存储成本。 y 对小型表进行索引可能不会产生优化效果,因为SQL Server在遍历索引以搜索数据 时,花费的时间可能会比简单的表扫描还长。 新概念 SQL Server 2005 教程 162 y 应使用SQL事件探查器和索引优化向导帮助分析查询,确定要创建的索引。为数 据库及其工作负荷选择正确的索引是非常复杂的,需要在查询速度和更新成本之 间取得平衡。窄索引(搜索关键字中只有很少的列的索引)需要的磁盘空间和维 护开销都更少。而另一方面,宽索引可以覆盖更多的查询。确定正确的索引集没 有简便的规则。经验丰富的数据库管理员常常能够设计出很好的索引集,但是, 即使对于不特别复杂的数据库和工作负荷来说,这项任务也十分复杂,费时和易 出错。可以使用索引优化向导使这项任务自动化。 y 可以在视图和计算列上指定索引。 一般来说,对表的查询都是通过主键来进行的,因此,首先应该考虑在主键上建立索 引。另外,对于连接中频繁使用的列(包括外键)也应作为建立索引的考虑选项。 由于建立索引需要一定的开销,而且,当使用INSERT或者UPDATE对数据进行插入和 更新操作时,维护索引也是需要花费时间和空间的。因此,没有必要对表中所有的列建立 索引。下面的情况则不考虑建立索引: y 从来不或者很少在查询中引用的列。 y 只有两个或者若干个值的列,例如性别(男或者女),也得不到建立索引的好处。 y 记录数目很少的表。 6.2 索引类型 可以依据索引的顺序和数据库的物理存储顺序是否相同而将索引分为两类:聚集索引 (Clustered Index)和非聚集索引(Non-clustered Index)。而这都使用的是B-Tree索引。 唯一索引(UNIQUE Index)可以确保索引列不包含重复的值。组合索引是使用表中的 不止一列对数据进行索引的索引。 6.2.1 B-Tree索引结构 B-Tree(Balanced Tree,平衡树)的顶端结点称为根结点(Root Node),底层结点称为 叶结点(Leaf Node),在根结点和叶结点之间的称为中间结点(Intermediate Node)。B-Tree 数据结构从根结点开始,以左右平衡的方式排列数据,中间可以根据需要分成许多层,如 图6.1所示。 因为B-Tree的结构非常适合于检索数据,所以在SQL Server中采用该结构来建立索引页 和数据页。 163 第6章 Chapter 06 提高检索效率的索引 图 6.1 B-Tree 的数据结构 6.2.2 聚集索引和非聚集索引 聚集索引和非聚集索引都是使用B-Tree的结构来建立的,而且都包括索引页和数据页, 其中索引页用来存放索引和指到下一层的指针,数据页用来存放记录。 聚集索引保证数据库表中记录的物理顺序与索引顺序相同,而在非聚集索引中,数据 库表中记录的物理顺序与索引顺序可以不相同。一个表中只能有一个聚集索引,而表中的 每一列上都可以有自己的非聚集索引。 1. 聚集索引 聚集索引的B-Tree是由下而上构建的,一个数据页(索引页的叶结点)包含一笔记录, 再由多个数据页生成一个中间结点的索引页。接着由数个中间结点的索引页合成更上层的 索引页,组合后会生成最顶层的根结点的索引页,如图6.2所示。 图 6.2 聚集索引的数据结构 在聚集索引的数据页中,记录是已经依照顺序排列好的,当进行查询时,即可从根结 根结点 ………… … …………… 中间结点 叶结点 根结点 中间结点 叶节点/数据页 新概念 SQL Server 2005 教程 164 点处,一层一层向下寻找。 当新增或者删除记录时,可能会影响到每一个索引页所能够容纳的索引数目,可能需 要将索引页进行分隔或者合并,而B-Tree的结构与中间结点的数量以及深度就有可能会改 变。 聚集索引确定表中数据的物理顺序,对于那些经常要搜索范围值的列特别有效。使用 聚集索引找到包含第一个,值的行后,便可以确保包含后续索引值的行在物理相邻。例如, 如果应用程序执行的查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到 包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此 类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将 该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。 注 意 定义聚集索引键时使用的列越少越好,这一点很重要。如果定义了一个大型的聚集 索引键,则同一个表上定义的任何非聚集索引都将增大许多,因为非聚集索引条目包含聚 集键。 在创建聚集索引之前,应该先了解数据是如何被访问的。可考虑将聚集索引用于下面 几种情况: y 包含大量非重复值的列。 y 使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、<和<=。 y 被连续访问的列。 y 返回大型结果集的查询。 y 经常被使用联接或GROUP BY子句的查询访问的列。一般来说,这些是外键列。 对ORDER BY或GROUP BY子句中指定的列进行索引,可以使SQL Server不必对数 据进行排序,因为这些行已经排序。这样可以提高查询性能。 y OLTP类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。 应在主键上创建聚集索引。 对于频繁更改的列,则不适合创建聚集索引。因为这将导致整行移动(因为SQL Server 必须按物理顺序保留行中的数据值),而在大数据量事务处理系统中,这样操作则数据很 容易丢失。 2. 非聚集索引 非聚集索引与书中的索引类似。数据存储在一个地方,索引存储在另一个地方,索引 带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存储,而表中的信息按另 一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行 具有任何特定的顺序。 非聚集索引与聚集索引一样有B-Tree结构,但是有两个重大差别: y 数据行不按非聚集索引键的顺序排序和存储。 y 非聚集索引的叶层不包含数据页。相反,叶结点包含索引行。每个索引行包含非 165 第6章 Chapter 06 提高检索效率的索引 聚集键值以及一个或多个行定位器,这些行定位器指向有该键值的数据行(如果 索引不唯一,则可能是多行)。 非聚集索引的数据结构如图6.3所示。与使用书中索引的方式相似,SQL Server 2005在 搜索数据值时,先对非聚集索引进行搜索,找到数据值在表中的位置,然后从该位置直接 检索数据。这使非聚集索引成为精确匹配查询的最佳方法,因为索引包含描述查询所搜索 的数据值在表中的精确位置的条目。 有些书籍包含多个索引。例如,一本介绍园艺的书可能会包含一个植物通俗名称索引 和一个植物学名索引,因为这是读者查找信息的两种最常用的方法。对于非聚集索引也是 如此。可以为在表中查找数据时常用的每个列创建一个非聚集索引。 图 6.3 非聚集索引的数据结构 在创建非聚集索引之前,同样需要了解数据是如何被访问的。可考虑将非聚集索引用 于下面的情况: y 包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其他列)。如 果只有很少的非重复值,如只有1和0,则大多数查询将不使用索引,因为此时使 用表扫描通常更有效。 y 不返回大型结果集的查询。 y 返回精确匹配的查询的搜索条件(WHERE子句)中经常使用的列。 y 经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列 上创建多个非聚集索引,在任何外键列上创建一个聚集索引。 y 在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。 根结点 中间结点 叶结点/数据页 新概念 SQL Server 2005 教程 166 6.2.3 唯一索引和组合索引 唯一索引(UNIQUE Index)表示表中任何两笔记录的索引值都不相同,与表的主键类 似。它可以确保索引列不包含重复的值。在多列唯一索引的情况下,该索引可以确保索引 列中每个值组合都是唯一的。 组合索引是将两个或者多个字段组合起来的索引,而单独的字段允许不是唯一的值。 例如,可以将姓名分为“姓”和“名”两个字段,如果允许同姓或同名的记录存在,但不 允许有任何两笔记录既同名又同姓,则可以将“姓”和“名”两个字段设为复合索引。 6.3 创建索引 SQL Server提供了两种方法来创建索引: y 直接创建索引 使用CREATE INDEX语句或者SQL Server Management Studio来直 接创建索引。 y 间接创建索引 使用CREATE TABLE语句创建表时,或者使用ALTER TABLE修 改表时,如果指定PRIMARY KEY约束或者UNIQUE约束,则SQL Server自动为这 些约束创建索引。 在创建索引时,需要指定索引的特征。这些特征包括下面几项: y 聚集还是非聚集。 y 唯一还是不唯一。 y 单列还是多列。 y 索引中的列顺序为升序还是降序。 y 覆盖还是非覆盖。 还可以自定义索引的初始存储特征,通过设置填充因子优化其维护,并使用文件和文 件组自定义其位置以优化性能。 本节主要介绍直接创建索引的方法,包括使用SQL语言和使用SQL Server Management Studio来创建索引。至于间接创建索引,可以参考附录B。 注 意 当前数据库正在备份时不能在其上创建索引。 6.3.1 通过SQL Server Management Studio创建索引 下面在bookdb数据库中的book表上创建一个名称为BookID的索 引。操作步骤如下: 打开SQL Server Management Studio窗口,依次选择“数据库” | bookdb |“表”| dbo.book选项,然后在“索引”处右击鼠标,在打开 的快捷菜单中执行“新建索引”命令,打开“新建索引”窗口。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第6章\创建索 引.avi。 167 第6章 Chapter 06 提高检索效率的索引 在“索引名称”文本框中输入索引名称,这里输入bookID。 单击“添加”按钮,打开“从‘dbo.book’中选择列”对话框,如图6.4所示。 图 6.4 “从‘dbo.book’中选择列”对话框 单击“确定”按钮,返回到“新建索引”窗口,如图6.5所示。 图 6.5 “新建索引”窗口 设置其他选项,例如是创建聚集索引还是创建聚集索引;是否创建唯一索引等。 在“选择页”列表中,选择“选项”选项,可打开“选项”选项卡。在此选项卡 中,可以设置其他一些选项。 完成后,单击“确定”按钮,即可创建一个新的索引。 提 示 在SQL Server中,Transact-SQL提供了一组DBCC(Database Consistency Checker)语 句,用来检查和修正数据库中的信息与问题。例如,可以使用DBCC SHOW_STATISTICS 语句来查看索引的统计结果。 该选项处于选中状态,表 示索引以降序排列 新概念 SQL Server 2005 教程 168 6.3.2 使用SQL语言创建索引 只有表或视图的所有者才能为表创建索引。表或视图的所有者可以随时创建索引,无 论表中是否有数据。可以通过指定限定的数据库名称,为另一个数据库中的表或视图创建 索引。前面介绍了使用企业管理器和向导来创建索引的操作步骤,下面介绍使用SQL语句 来创建索引的语法格式,并详细介绍各个选项的含义及其注意事项。 创建索引是通过CREATE INDEX语句来完成的,其语法格式如下: CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name ON { table | view } ( column [ ASC | DESC ] [ , …n ] ) [ WITH < index_option > [ , …n] ] [ ON filegroup ] < index_option > ::= { PAD_INDEX | FILLFACTOR = fillfactor | IGNORE_DUP_KEY | DROP_EXISTING | STATISTICS_NORECOMPUTE | SORT_IN_TEMPDB } 各选项的含义如下: y UNIQUE 为表或视图创建唯一索引(不允许存在索引值相同的两行)。视图上的 聚集索引必须是UNIQUE索引。 y CLUSTERED 创建聚集索引。如果没有指定CLUSTERED,则创建非聚集索引。 具有聚集索引的视图称为索引视图。必须先为视图创建唯一聚集索引,然后才能 为该视图定义其他索引。 y NONCLUSTERED 创建一个指定表的逻辑排序的对象,即非聚集索引。每个表 最多可以有249个非聚集索引(无论这些非聚集索引的创建方式如何——是使用 PRIMARY KEY和UNIQUE约束隐式创建,还是使用CREATE INDEX显式创建)。 每个索引均可以提供对数据的不同排序次序的访问。对于索引视图,只能为已经 定义了聚集索引的视图创建非聚集索引。因此,索引视图中非聚集索引的行定位 器一定是行的聚集键。 y index_name 是索引名。索引名在表或视图中必须唯一,但在数据库中不必唯一。 索引名必须遵循标识符规则。 y table 包含要创建索引的列的表。可以选择指定数据库和表所有者。 y view 要建立索引的视图的名称。必须使用SCHEMABINDING定义视图才能在视 图上创建索引。视图定义也必须具有确定性。如果选择列表中的所有表达式、 WHERE和GROUP BY子句都具有确定性,则视图也具有确定性。而且,所有键列 必须是精确的。只有视图的非键列可能包含浮点表达式(使用float数据类型的表达 式),而且float表达式不能在视图定义的其他任何位置使用。 169 第6章 Chapter 06 提高检索效率的索引 注 意 在创建索引视图或对参与索引视图的表中的行进行操作时,有7个选项必须指派特定 的值。SET选项ARITHABORT、CONCAT_NULL_YIELDS_NULL、QUOTED_IDENT- IFIER 、 ANSI_NULLS 、 ANSI_PADDING 和 ANSI_WARNING 必须为ON 。 SET 选项 NUMERIC_ROUNDABORT必须为OFF。如果与上述设置有所不同,对索引视图所引用的 任何表执行的数据修改语句(INSERT、UPDATE、DELETE)都将失败,SQL Server会显 示一条错误信息,列出所有违反设置要求的SET选项。 y column 应用索引的列。指定两个或多个列名,可为指定列的组合值创建组合索 引。在table后的圆括号中列出组合索引中要包括的列(按排序优先级排列)。 y [ ASC | DESC ] 确定具体某个索引列的升序(ASC)或降序(DESC)排序方向。 默认设置为ASC(升序)。 y n 表示可以为特定索引指定多个column的占位符。 y ON filegroup 在给定的filegroup(文件组)上创建指定的索引。该文件组必须已 经通过执行CREATE DATABASE或ALTER DATABASE创建。 y < index_option > 指定创建索引的选项。将在下面详细介绍。 例如,下面的SQL语句用于在bookdb数据库中的authors表中的author_id列上创建一个 非聚集索引: SET NOCOUNT OFF --返回计数 USE bookdb --判断是否存在author_id_ind,若存在,则先删除 IF EXISTS (SELECT name FROM sysindexes WHERE name = 'author_id_ind') DROP INDEX authors.author_id_ind GO USE bookdb CREATE INDEX author_id_ind ON authors(author_id) GO 下面的示例为clients表的client_id列创建索引,并且强制唯一性。因为指定了 CLUSTERED子句,所以该索引将对磁盘上的数据进行物理排序: SET NOCOUNT OFF --返回计数 USE bookdb IF EXISTS (SELECT name FROM sysindexes WHERE name = 'client_id_ind') DROP INDEX clients.client_id_ind GO USE bookdb CREATE UNIQUE CLUSTERED INDEX client_id_ind ON clients(client_id) GO 新概念 SQL Server 2005 教程 170 6.3.3 创建索引的选项设置 在创建索引时,可以指定填充因子等选项。在前面,对这些选项做了简单介绍,下面 详细介绍这些选项及其注意事项。 1. PAD_INDEX 指定索引中间级中每个页(结点)上保持开放的空间。PAD_INDEX选项只有在指定了 FILLFACTOR时才有用,因为PAD_INDEX使用由FILLFACTOR所指定的百分比。默认情况 下,给定中间级页上的键集,SQL Server将确保每个索引页上的可用空间至少可以容纳一 个索引允许的最大行。如果为FILLFACTOR指定的百分比不够大,无法容纳一行,SQL Server将在内部使用允许的最小值替代该百分比。 提 示 中间级索引页上的行数永远都不会小于两行,无论 FILLFACTOR 的值有多小。 2. FILLFACTOR = fillfactor 指定在SQL Server创建索引的过程,各索引页叶级的填满程度。如果某个索引页填满, SQL Server就必须花时间拆分该索引页,以便为新行腾出空间,这需要很大的开销。对于 更新频繁的表,选择合适的FILLFACTOR值将比选择不合适的FILLFACTOR值获得更好的 更新性能。FILLFACTOR的原始值将在sysindexes中与索引一起存储。 如果指定了FILLFACTOR,SQL Server会向上舍入每页要放置的行数。例如,发出 CREATE CLUSTERED INDEX …FILLFACTOR = 33将创建一个FILLFACTOR为33%的聚 集索引。假设SQL Server计算出每页空间的33%为5.2行。SQL Server将其向上舍入,这样, 每页就放置6行。 用户指定的FILLFACTOR值可以从1~100。如果没有指定值,默认值为0。如果 FILLFACTOR设置为0,则只填满叶级页。只有不会出现INSERT或UPDATE语句时(例如 对只读表),才可以使用FILLFACTOR 100。如果FILLFACTOR为100,SQL Server将创建 叶级页100%填满的索引。如果在创建FILLFACTOR为100%的索引之后执行INSERT或 UPDATE,会对每次INSERT操作以及有可能每次UPDATE操作进行页拆分。 注 意 用某个FILLFACTOR值创建聚集索引会影响数据占用存储空间的数量,因为SQL Server在创建聚集索引时会重新分布数据。 例如,下面的例子使用FILLFACTOR子句,将其设置为100。FILLFACTOR为100将完 全填满每一页,只有确定表中的索引值永远不会更改时,该选项才有用。 IF EXISTS (SELECT name FROM sysindexes WHERE name = 'telphone_ind') DROP INDEX authors.telphone_ind GO USE bookdb 171 第6章 Chapter 06 提高检索效率的索引 CREATE INDEX telphone_ind ON authors(telphone) WITH FILLFACTOR = 100 GO 3. IGNORE_DUP_KEY 控制当尝试向属于唯一聚集索引的列插入重复的键值时所发生的情况。如果为索引指 定了IGNORE_DUP_KEY,并且执行了创建重复键的INSERT语句,SQL Server将发出警告 消息并忽略重复的行。 如果没有为索引指定IGNORE_DUP_KEY,SQL Server会发出一条警告消息,并回滚整 个INSERT语句。 4. DROP_EXISTING 指定应除去并重建已命名的先前存在的聚集索引或非聚集索引。指定的索引名必须与 现有的索引名相同。因为非聚集索引包含聚集键,所以在除去聚集索引时,必须重建非聚 集索引。如果重建聚集索引,则必须重建非聚集索引,以便使用新的键集。 为已经具有非聚集索引的表重建聚集索引时(使用相同或不同的键集), DROP_EXISTING子句可以提高性能。 DROP_EXISTING子句代替了先对旧的聚集索引执行DROP INDEX语句,然后再对新 的聚集索引执行CREATE INDEX语句的过程。非聚集索引只需重建一次,而且还只是在键 不同的情况下才需要。 提 示 如果键没有改变(提供的索引名和列与原索引相同),则DROP_EXISTING子句不会 重新对数据进行排序。在必须压缩索引时,这样做会很有用。并且无法使用 DROP_EXISTING子句将聚集索引转换成非聚集索引;不过,可以将唯一聚集索引更改为 非唯一索引,反之亦然。 5. STATISTICS_NORECOMPUTE 指定过期的索引统计不会自动重新计算。若要恢复自动更新统计,可执行没有 NORECOMPUTE子句的UPDATE STATISTICS。 如果禁用分布统计的自动重新计算,可能会妨碍SQL Server查询优化器为涉及该表的 查询选取最佳执行计划。 6. SORT_IN_TEMPDB 指定用于生成索引的中间排序结果将存储在tempdb数据库中。如果tempdb与用户数据 库不在同一磁盘集,则此选项可能减少创建索引所需的时间,但会增加创建索引时使用的 磁盘空间。 6.3.4 创建索引的空间考虑 创建聚集索引要求数据库中的可用空间大约为数据大小的1.2倍。该空间不包括现有表 新概念 SQL Server 2005 教程 172 占用的空间。将对数据进行复制以创建聚集索引,旧的无索引数据将在索引创建完成后删 除。使用DROP_EXISTING子句时,聚集索引所需的空间数量与现有索引的空间要求相同。 所需的额外空间可能还受指定的FILLFACTOR的影响。 在SQL Server 2005中创建索引时,可以使用SORT_IN_TEMPDB选项指示数据库引擎 在tempdb中存储中间索引排序结果。如果tempdb在不同于用户数据库所在的磁盘集上,则 此选项可能减少创建索引所需的时间,但会增加用于创建索引的磁盘空间。除了在用户数 据库中创建索引所需的空间外,tempdb还必须有大约相同的额外空间来存储中间排序结果。 6.3.5 在视图和计算列上创建索引 在SQL Server 2005中,还可以在计算列和视图上创建索引。在视图上创建唯一聚集索 引可以提高查询性能,因为视图存储在数据库中的方式与具有聚集索引的表的存储方式相 同。 UNIQUE或PRIMARY KEY只要满足所有索引条件,就可以包含计算列。具体说来就 是,计算列必须具有确定性,必须精确,且不能包含text、ntext或image列。 例如,下面的SQL语句是在test数据库中创建一个表t1,然后在此表的计算列c上创建一 个索引: USE test CREATE TABLE t1 (a int, b int, c AS a*b) GO CREATE INDEX Idx1 ON t1(c) GO INSERT INTO t1 VALUES ('1', '0') GO 提 示 在通过数字或float表达式定义的视图上使用索引所得到的查询结果,可能不同于不 在视图上使用索引的类似查询所得到的结果。这种差异可能是由对基础表进行INSERT、 DELETE或UPDATE操作时的舍入错误引起的。 6.4 索引的查看和删除 索引的查看和删除均有两种方法:使用SQL Server Management Studio和SQL语言。 6.4.1 使用SQL Server Management Studio 使用SQL Server Management Studio查看和删除索引的操作步骤如下: 打开SQL Server Management Studio窗口,打开要删除的索引所在的表,打开“索 引”。 右击要查看的索引,在打开的快捷菜单上,执行“属性”命令,打开索引属性窗 口,可以查看和修改索引的有关设置。 设置完成后单击“确定”按钮即可。 173 第6章 Chapter 06 提高检索效率的索引 要删除索引,可右击要删除的索引,在打开的快捷菜单上执行“删除”命令,打 开“删除对象”窗口,单击“确定”按钮即可。 6.4.2 使用SQL语言 要查看索引信息,可使用存储过程sp_helpindex。例如,下面的SQL语句用于显示book 表上的索引信息: USE bookdb GO EXEC sp_helpindex book GO 执行结果如下: index_name index_description index_keys ----------- --------------------------------------- --------- BookID nonclustered, unique located on PRIMARY book_id PK_book clustered, unique, primary key located on PRIMARY book_id 删除索引使用DROP INDEX语句,其语法格式如下: DROP INDEX 'table.index | view.index' [ , …n ] 其中table和view是索引列所在的表或索引视图;index是要除去的索引名称。索引名必 须符合标识符的规则。n表示可以指定多个索引的占位符。 例如,下面的SQL语句是删除clients表中的索引client_id_ind: USE bookdb GO DROP INDEX clients.client_id_ind GO 6.5 全文索引 在数据库中检索记录时,使用索引是提高效率的好方法,但是索引一般是建立在数字 或者较短的字符串字段上面。因为当表有新增或者更改操作时,更新索引B-Tree结构的速 度越快越好,所以一般不会选择那些很长的字段来创建索引。 但是在实际工作中,可能会需要使用那些比较长的字符串字段来检索数据,这就需要 使用SQL Server提供的全文索引。 全文索引和全文检索是从SQL Server 7.0开始新增的功能。已能够对数据库中的字符类 型的字段进行索引,并通过索引实现全文搜索查询。 全文索引和常规索引的区别如表6.1所示。 新概念 SQL Server 2005 教程 174 表6.1 全文索引和常规索引的区别 全文索引 常规索引 使用存储过程创建和删除 使用CREATE INDEX或者约束定义创建,通过删除约 束或者DROP INDEX语句删除 只能通过任务调度或者执行存储过程来填充 全文索引 当插入、删除或者修改数据时,SQL Server会自动更新 索引内容 每个表只能有一个全文索引 每个表可以建立多个常规索引 同一个数据库中的多个全文索引可以组织为 一个全文目录 常规索引不能分组 全文索引存储在文件系统中 常规索引存储在数据库中 常规索引大多会选用数据类型为数字的字段,当新增或者更新数据时会自动更新索引 结构,并不会花太多时间。但是全文索引是用来整理字符串(一般长度都比较大)的,当 数据内容被更改或者新增时,全文索引会需要更多的时间去更新,因此,一般都设置在只 有很少的用户访问数据库时才进行整理。这与一般索引有很大的不同。 全文索引并不是存储在数据库中,而是存放在磁盘上的文件中,默认是在SQL Server 的安装目录下的FTDATA目录中,这样不会使数据库变得太大。 6.5.1 SQL Server FullText Search服务 要使用全文索引功能,必须启动SQL Server FullText Search服务 (SQL Server全文索引服务)。操作步骤如下: 打开“控制面板”,然后选择“管理工具”选项,双击“服 务”图标,打开“服务”窗口。 在右侧窗口中即可找到SQL Server FullText Search服务,如 图6.6所示。如果该服务没有启动,可右击该服务,然后执行快捷菜 单上的“启动”命令,即可启动该服务。 图 6.6 SQL Server FullText Search 服务 6.5.2 创建全文目录 全文目录是存放全文索引的地方,全文目录记录数据库中设置有全文索引的表字段以 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第6章\启动全 文索引服务.avi。 175 第6章 Chapter 06 提高检索效率的索引 及更新计划。因此在建立和使用全文索引之前,应该先建立全文目录。 全文索引包含在全文目录中。每个数据库可以包含一个或多个全文目录。一个目录不 能属于多个数据库,而每个目录可以包含一个或多个表的全文索引。一个表只能有一个全 文索引,因此每个有全文索引的表只属于一个全文目录。 创建全文目录可以使用SQL Server Management Studio,也可以使 用SQL语言来完成。使用SQL Server Management Studio创建全文目录 的操作步骤如下: 打开SQL Server Management Studio窗口,然后打开要创建全 文目录的数据库,例如bookdb。 在bookdb数据库上右击鼠标,选择“属性”命令,打开“数 据库属性-bookdb”对话框。在“选项页”栏中,选择“文件”选项,打开“文件”选项卡。 选择“使用全文索引”复选框,如图6.7所示。 图 6.7 单击“确定”按钮,关闭“数据库属性-bookdb”对话框。打开“存储”文件夹, 然后右击“全文目录”选项,在快捷菜单上执行“新建全文目录”命令,打开新建全文目 录窗口,如图6.8所示。 设置完成后,单击“确定”按钮,即可创建一个全文目录。 提 示 在创建全文目录后,可以通过其属性窗口进行选项设置。要删除全文目录,在该全 文目录上右击鼠标,然后执行“删除”命令即可。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第6章\创建全 文目录.avi。 新概念 SQL Server 2005 教程 176 图 6.8 “新建全文目录”窗口 也可以使用存储过程sp_fulltext_catalog建立和删除全文目录。其语法格式如下: sp_fulltext_catalog [ @ftcat = ] 'fulltext_catalog_name' , [ @action = ] 'action' [ , [ @path = ] 'root_directory' ] 各参数含义如下: y [@ftcat =] 'fulltext_catalog_name' 全文目录的名称。对于每个数据库,目录名必须 是唯一的。fulltext_catalog_name 的数据类型为sysname。 y [@action =] 'action' 将要执行的动作。action的数据类型为varchar(20),其取值如 表6.2所示。 表6.2 action取值及其含义 action 取值 含义 create 在文件系统中创建一个空的新全文目录,并且向 sysfulltextcatalogs 添加一行,该行 与 fulltext_catalog_name 及 root_directory(如果存在的话)值相关。在数据库内, fulltext_catalog_name 必须是唯一的 drop 将 fulltext_catalog_name 从文件系统中删除,并且删除 sysfulltextcatalogs 中相关的 行。如果此目录中包含一个或多个表的索引,此动作将失败。应执行 sp_fulltext_table 'table_name', 'drop',以除去目录中的表。如果目录不存在,就会显示错误 start_incremental 启动 fulltext_catalog_name 的增量填充。如果目录不存在,就会显示错误。如果一 个全文索引填充已经是活动的,那么就会显示一个警告,而不发生填充动作。使用 增量填充,只为全文索引检索那些更改过的行,但条件是被全文索引的表中存在一 个 timestamp 列 输入全文 目录名称。 设置全文目录的所有 者。可以通过单击右侧的 按钮进行选择。 设置目录 的保存位置。 177 第6章 Chapter 06 提高检索效率的索引 (续表) action 取值 含义 start_full 启动 fulltext_catalog_name 的完全填充。即使与此全文目录相关联的每一个表的每 一行都进行过索引,也会对其检索全文索引 stop 停止 fulltext_catalog_name 的索引填充。如果目录不存在,就会显示错误。如果已 经停止了填充,那么并不会显示警告 rebuild 重建 fulltext_catalog_name,方法是从文件系统中删除现有的全文目录,然后重建全 文目录,并使该全文目录与所有带有全文索引引用的表重新建立关联。重建并不更 改数据库系统表中的任何全文元数据,也不会对新创建的全文目录进行重新填充。 若要重新填充,必须使用 start_full 或 start_incremental 操作执行 sp_fulltext_catalog y [@path =] 'root_directory' 是针对create动作的根目录(并不是完整的物理路径)。 root_directory的数据类型为nvarchar(100),默认值为NULL,表示使用安装时指定 的默认位置。这是Mssql目录中的Ftdata子目录,例如D:\Program Files\Microsoft SQL Server\Mssql\Ftdata。指定的根目录必须驻留在同一台计算机的驱动器上,它不仅 包含驱动器号,而且不能是相对路径。不支持网络驱动器、可移动驱动器、软盘 及UNC路径。全文目录必须在与SQL Server实例相关联的本地硬盘上创建。 注 意 只有当action为create时,@path才有效。对于create以外的动作(stop、rebuild等), @path必须为NULL或被省略。 该存储过程返回0表示执行成功,返回1表示执行失败。 使用start_full动作在fulltext_catalog_name中创建全文数据的一个完整快照。使用 start_incremental动作只对数据库中更改过的行重新索引。对于增量索引,在表的一个列中 需要一个timestamp列。 全文目录及索引数据存储在某些文件中,这些文件创建在全文目录目录中。全文目录 目录作为@path指定目录中的子目录创建,如果未指定@path,则在服务器默认值全文目录 目录中创建。生成全文目录目录名称的方式可以保证它在服务器上是唯一的。因此,一个 服务器上所有的全文目录目录可以共享相同的路径。 提 示 只有sysadmin固定服务器角色和db_owner(或更高)固定数据库角色的成员才可以执 行sp_fulltext_catalog存储过程。 例如,下面的SQL语句在bookdb数据库中重建一个现有的全文目录BookDescrip- Catalog: USE bookdb EXEC sp_fulltext_catalog 'BookDescripCatalog', 'rebuild' 新概念 SQL Server 2005 教程 178 6.5.3 创建全文索引 全文索引必须在基表上定义,而不能在视图、系统表或临时表上定义。全文索引的定 义包括: y 能唯一标识表中各行的列(主键或候选键),而且不允许NULL值。 y 索引所覆盖的一个或多个字符串列。 全文索引由键值填充。每个键的项提供与该键相关联的重要词(干扰词或终止词除外)、 它们所在的列和它们在列中的位置等有关信息。 下面在bookdb数据库的book表上创建一个全文索引。操作步骤如 下: 在要创建全文索引的表(此处为book表)上右击鼠标,将鼠 标移到弹出的快捷菜单的“全文索引”选项上,然后执行“定义全文 索引”命令。 此时,打开“全文索引向导”对话框,并提示该向导可以完 成的操作,如图6.9所示。 图 6.9 “全文索引向导”对话框 单击“下一步”按钮,向导提示选择唯一索引,如图6.10所示。 图 6.10 选择唯一索引 使用该向导可以 完成的操作 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第6章\创建全 文索引.avi。 179 第6章 Chapter 06 提高检索效率的索引 从下拉列表框中选择唯一索引后,单击“下一步”按钮,向导提示选择表中的列, 如图6.11所示。 图 6.11 选择表中的列 选择完成后,单击“下一步”按钮,向导提示选择更改跟踪,如图6.12所示。 图 6.12 选择全文目录 单击“下一步”按钮,向导提示选择全文目录或者新建一个全文目录,如图6.13 所示。 图 6.13 选择或创建目录 选择全文目录 新建一个全文目录 只有属于字符数据类型 的列才会显示在该对话 框的列表框中 新概念 SQL Server 2005 教程 180 单击“下一步”按钮,向导提示定义填充计划。可以通过单击“新建表计划”按 钮新建一个表计划,如图6.14所示。 图 6.14 定义填充计划 单击“下一步”按钮,向导显示用户所做的选择,如图6.15所示。 图 6.15 用户所作设置摘要 单击“完成”按钮即可开始创建全文索引,并出现一个进度对话框,提示正在进 行的操作。完成后出现了一提示对话框,单击“关闭”按钮即可创建一个全文索引。 删除全文索引除了使用SQL Server Management Studio外,还可以使用sp_fulltext_table 存储过程,例如要删除上面创建的全文索引,可以使用下述命令: USE bookdb EXEC sp_fulltext_table 'BookDescripCatalog', 'drop' 设置填充类型。 181 第6章 Chapter 06 提高检索效率的索引 这里不执行上述语句,也即不进行删除操作,因为下面还要使用BookDescripCatalog 全文索引。 6.5.4 全文查询 全文索引是用于执行两个Transact-SQL谓词的组件,以便根据全文检索条件对行进行 测试: y CONTAINS y FREETEXT Transact-SQL还包含两个返回符合全文检索条件的行集的函数: y CONTAINSTABLE y FREETEXTTABLE SQL Server将搜索条件发送给SQL Server FullText Search服务。SQL Server FullText Search服务查找所有符合全文检索条件的键并将它们返回给SQL Server。SQL Server随后使 用键的列表来确定表中要处理的行。 1. CONTAINS 函数 一个谓词,用于搜索包含基于字符的数据类型的列,该列与单个词和短语,以及与另 一个词一定范围之内的近似词精确或模糊(不太精确的)匹配或者加权匹配。 CONTAINS可以搜索: y 词或短语; y 词或短语的前缀; y 另一个词附近的词; y 由另一个词的词尾变化生成的词(例如,词drive是drives、drove、driving和driven 词尾变化的词干); y 比另一个词具有更高加权的词。 (1)词或者短语 指定对每个精确词(单字节语言中没有空格或标点符号的一个或多个字符)或短语(单 字节语言中由空格和可选的标点符号分隔的一个或多个连续的词)的匹配。 应该使用双引号("")将短语括起来。短语中词出现的顺序必须与它们出现在数据库 列中的顺序相同。对词或短语中字符的搜索是区分大小写的。全文索引列中的干扰词(例 如a、and或the)不存储在全文索引中。如果在单个词搜索中使用干扰词,那么SQL Server 将返回一个错误信息指明查询中只有干扰词出现。SQL Server在目录\Mssql\Ftdata \Sqlserver\Config下包括干扰词的标准列表。 例如,blue berry、blueberry和Microsoft SQL Server都是有效的简单术语。 标点符号被忽略。因此,CONTAINS(testing, "computer failure")将匹配具有"Where is my computer?Failure to find it would be expensive."值的行。 例如,下面的SQL语句搜索包含“实例”两个字的书籍名称和价格: 新概念 SQL Server 2005 教程 182 USE bookdb GO SELECT book_name,price FROM book WHERE CONTAINS(book_name, '实例') GO 执行结果如下: book_name price ------------------------------------------- ------- 3D Studio MAX实例精选 35.0 (2)词或者短语的前缀 指定以指定文本开始的匹配词或短语。将前缀术语用双引号("")引起来并在后一个 引号前添加一个星号(*),这样将匹配在星号前指定的所有以简单术语打头的文本。例如, 应这样指定该子句:CONTAINS (column, '"text*"')。 星号匹配零、一个或多个字符(属于词或短语中的词根或词)。如果未用双引号将文 本与星号括起来,如CONTAINS (column, 'text*') 中所示,那么全文检索将把星号作为字符 处理并搜索text*的精确匹配项。 当前缀是一个短语时,短语中包含的每个词都被认为是一个单独的前缀。因此,指定 一个“local wine *”前缀术语的查询将匹配任何具有“local winery”、“locally wined and dined” 等文本的行。 例如,下面的SQL语句是查询以Win开始的书名: USE bookdb GO SELECT book_name,price FROM book WHERE CONTAINS(book_name, '"Win*"') GO 执行结果如下: book_name price -------------------------------------------- ------- Windows Vista看图速成 30 Windows 2003 Server网络管理 45 但是如果修改如下: USE bookdb GO SELECT book_name,price FROM book WHERE CONTAINS(book_name, 'Win*') GO 则不会检索到任何记录,因为它查找的是包含“Win*”字符串的记录,而表中没有这 样的记录。 183 第6章 Chapter 06 提高检索效率的索引 (3)使用相近的字符串来查询 指定匹配的词或短语,这些词或短语必须彼此接近。与AND运算符相似:两者都要求 在被搜索的列中有多个词或短语存在。 要使用相近的字符串进行查询,可以使用NEAR或者~子句。指明NEAR或~运算符左边 的词或短语应该与NEAR或~运算符右边的词或短语近似接近。可以链接多个近似术语。 例如,下面的SQL语句查询关于3D的实例类书籍: USE bookdb GO SELECT book_name,price FROM book WHERE CONTAINS(book_name, '3D NEAR 实例') GO 执行结果如下: book_name price ------------------------------------------- ------- 3D Studio MAX实例精选 35 (4)衍生字 衍生字主要是针对英文的,例如,英文单词的现在时、过去时、将来时和分词不等式 等,都是衍生字。 可以使用INFLECTIONAL关键字,它指定了应匹配单数与复数以及名词、动词和形容 词的性别与中性形式。也应匹配各种动词时态。 例如,下面的SQL语句查询具有dry形式的词的所有产品:dried和drying等: USE AdventureWorks GO SELECT Name FROM Product WHERE CONTAINS(Name, ' FORMSOF (INFLECTIONAL, dry) ') GO 注 意 在执行上述语句时,可能会发生错误,因为没有给AdventureWorks数据库建立全文 索引。 (5)赋予字符串权重 指定匹配词和短语列表的匹配行(由查询返回),可以对每行随意给定一个加权值。 此时应使用ISABOUT关键字。而WEIGHT(weight_value)指定数值介于0.0~1.0之间的加 权值。要查询的字符串中的每个组件可能包含一个权重。通过这个权重,可以改变查询的 各个部分怎样来影响指派给与查询匹配的每行的等级值。但是如果存在与任意一个 ISABOUT参数的匹配,则返回一行,不论是否指派了加权值。 例如,下面的SQL语句就是使用了权重的例子,赋予“实例”字符串0.8的权重,赋予 “网络”字符串0.4的权重: 新概念 SQL Server 2005 教程 184 USE bookdb SELECT book_name,price FROM book WHERE CONTAINS(book_name, 'ISABOUT ( 实例 weight(.8), 网络 weight(.4))' ) GO 执行结果如下: book_name price -------------------------------------------- ------- 3D Studio MAX实例精选 35 Windows 2003 Server网络管理 45 (6)使用变量 在CONTAINS关键字中,还可以使用变量来进行查询。下例就是使用变量而非特定的 搜索术语进行查询的例子: USE bookdb GO DECLARE @SearchWord varchar(30) SET @SearchWord ='网络管理' SELECT book_name,price FROM book WHERE CONTAINS(book_name, @SearchWord) GO 执行结果如下: book_name price ------------------------------------------- - ------ Windows 2003 Server网络管理 45 2. FREETEXT 函数 用于搜索含有基于字符的数据类型的列,其中的值符合在搜索条件中所指定文本的含 义,但不符合表达方式。使用FREETEXT时,全文查询引擎内部将要搜索的字符串拆分为 若干个搜索词,并赋予每个词以不同的加权,然后查找匹配。 其语法格式为: FREETEXT ( { column | * } , 'freetext_string' ) 各参数含义如下: y column 已经注册全文检索的特定列的名称。具有字符串数据类型的列是可进行 全文检索的有效的列。 y *(星号) 指定所有已注册用于全文检索的列均用于搜索给定的freetext_string。 y freetext_string 要在指定的column中进行搜索的文本。可以输入任何文本,包括单 词、短语或句子。所输入的文本与语法无关。 例如,下面就是一个使用FREETEXT关键字的例子: USE bookdb GO DECLARE @SearchWord varchar(30) 185 第6章 Chapter 06 提高检索效率的索引 SET @SearchWord ='网络管理' SELECT book_name,price FROM book WHERE FREETEXT(book_name, @SearchWord) GO 执行结果如下: book_name price ------------------------------------------- ------- Windows 2003 Server网络管理 45 注 意 使用FREETEXT的全文查询没有使用CONTAINS的全文查询精度高。SQL Server全文 检索引擎识别重要的字词和短语。保留关键字或通配符字符都不具有特殊含义,而它们指 定在CONTAINS谓词的参数中时则通常具有含义。 3. CONTAINSTABLE 函数 CONTAINSTABLE函数会返回一个检索结果的表内容。CONTAINSTABLE除了包括建 立全文索引的表的所有的字段外,还增加了一个KEY字段和RANK字段。KEY字段用来放 置全文索引的键值,而查询完毕后,每一笔找到的记录会依据查询符合的程度产生一个 RANK值,存放在RANK字段中。 CONTAINSTABLE可以在SELECT语句的FROM子句中引用,就好像它是一个常规的 表名称。CONTAINSTABLE函数使用与CONTAINS关键词相同的搜索条件。其语法格式如 下: CONTAINSTABLE ( table , { column | * } , ' < contains_search_condition > ' [ , top_n_by_rank ] ) 其中table为用于全文查询的表的名称,top_n_by_rank指定只返回以降序排列的前n个最 高等级的匹配项。仅当指定了整数值n时应用。其余参数和CONTAINS关键词的参数含义相 同。 例如,下面的SQL语句就是使用CONTAINSTABLE函数的例子: USE bookdb GO SELECT book_name,price,TTTable.[KEY],TTTable.Rank FROM book INNER JOIN CONTAINSTABLE(book,book_name,'实例') AS TTTable ON book_id=TTTable.[KEY] GO 执行结果如下: book_name price KEY Rank ------------------------------------ ------ ------- ------- 3D Studio MAX实例精选 35 2 48 提 示 由于KEY为Transact-SQL的保留字,因此,在上面的使用中,应该加上中括号([]) 号。 新概念 SQL Server 2005 教程 186 4. FREETEXTTABLE 函数 FREETEXTTABLE函数也可以在SELECT语句的FROM子句中像常规表名称一样进行 引用。其语法格式如下: FREETEXTTABLE ( table , { column | * } , 'freetext_string' [ , top_n_by_rank ] ) 其中的各个参数含义和CONTAINSTABLE函数的参数含义相同。 和CONTAINSTABLE函数类似,FREETEXTTABLE函数返回的表也带有KEY和Rank 字段。 例如,下面的SQL语句用于查询: USE bookdb GO SELECT book_name,price,FTable.[KEY],FTable.Rank FROM book INNER JOIN FREETEXTTABLE(book,book_name,'实例') AS FTable ON book_id=FTable.[KEY] GO 执行结果如下: book_name price KEY Rank --------------------------------- ------- ------- ------- 3D Studio MAX实例精选 35 2 130 6.6 课堂演练 在boarddb数据库的board表上建立全文索引,这样可以对公告内容进行全文搜索。建立 全文索引的操作步骤如下: 打开SQL Server Management Studio窗口。 首先在boarddb数据库上建立一个全文目录名称采用默认值即可。详细步骤可以参 考6.5.2节的介绍。 在boarddb数据库的board表上右击鼠标,在弹出的快捷菜单中选择“全文索引”| “定义全文索引”命令。 依照提示建立board表的全文索引。 6.7 小结 本章介绍了索引的概念,包括聚集索引和非聚集索引,并介绍了索引的创建、删除和 使用。最后介绍了基于字符串数据类型的全文索引的使用。 聚集索引和非聚集索引都采用B-Tree结构,而且都包含索引页和数据页。但是聚集索 引表的物理顺序与索引顺序相同。非聚集索引表的物理顺序与索引顺序不同。每一个表只 能有一个聚集索引,但可以有多个非聚集索引。使用聚集索引检索的速度要比使用非聚集 187 第6章 Chapter 06 提高检索效率的索引 索引快。 全文索引用来检索表字段中的字符串或者组合字符串,全文索引必须在基表上定义, 而不能在视图、系统表或临时表上定义。全文索引并不是存储在数据库中,而是存放在磁 盘上的文件中,默认是在SQL Server的安装目录下的FTDATA目录中,这样不会造成数据 库变得太大。 使用全文索引有4种方式:使用CONTAINS和FREETEXT关键字或者使用CONTAINST- ABLE和FREETEXTTABLE函数。 6.8 课后练习 6.8.1 选择题和简答题 (1)某公司有数据库,其中有一个表包含几十万个数据,但是用户抱怨说查询速度太 慢,下面哪种方法能最好地提高查询速度: A. 收缩数据库 B. 减少数据库占用的空间 C. 建立聚集索引和非聚集索引 D. 换个高档的服务器 (2)使用索引的优点和缺点是什么? (3)简述聚集索引和非聚集索引的区别。 (4)简述全文索引的含义及其与常规索引的不同之处。 6.8.2 操作题 (1)在SQL Server Management Studio中,为bookdb数据库的orderform表创建索引。 (2)利用SQL语句在bookdb数据库的clients表上的创建索引。 第 7 章 SQL 高级使用 07 Chapter 本章导读: ” 数据总结 ” 连接查询和子查询 ” UNION关键词的使用 ” 错误处理 ” ntext、text和image数据的检索 ” ntext、text和image数据的更改 ” 事务处理 ” 数据的并发性问题 ” 数据锁定 ” 游标使用 7.1 SELECT高级查询 在5.2.2小节中,介绍了SELECT的完整语法,并对SELECT的简单使用做了介绍。本节 主要介绍数据汇总、联接查询、子查询和UNION关键词的使用。 7.1.1 数据汇总 为决策支持系统生成聚合事务的汇总报表是一项复杂并且相当消耗资源的工作。SQL Server 2005提供两个灵活且强大的组件,用于生成SQL Server 2005 Analysis Services。这些 组件是程序员在执行SQL Server数据的多维分析时应当使用的主要工具。 这两个组件为: y 数据转换服务(DTS) DTS支持提取事务数据并将这些数据转换到数据仓库或数 据集合中的汇总聚合中。 y Microsoft SQL Server Analysis Services Analysis Services将数据仓库中的数据组 织到含有预先计算好的汇总信息的多维数据集中,以对复杂的分析查询提供快速 响应。Analysis Services还提供一套向导,用于定义分析处理过程中所用的多维结 构,并提供用于管理分析结构的Microsoft管理控制台管理单元。 但是对于生成简单汇总报表的应用程序,可使用下列Transact-SQL元素: y CUBE或ROLLUP运算符 这两者是SELECT语句的GROUP BY子句的一部分。 189 第7章 Chapter 07 SQL高级使用 y COMPUTE或COMPUTE BY运算符 这两者也与GROUP BY相关联。 1. 聚合函数 数据库的一个最大的特点就是将各种分散的数据按照一定规律、条件进行分类组合, 最后得出统计结果。SQL Server提供了聚合函数,用来完成一定的统计功能。常用的几个 聚合函数如表7.1所示。 表7.1 常用的几个聚合函数 函数 说明 AVG 求平均值 COUNT 返回组中项目的数量,返回值为 int 类型 COUNT_BIG 返回组中项目的数量,返回值为 bigint 类型 MAX 求最大值 MIN 求最小值 SUM 求和 STDEV 计算统计标准偏差 VAR 统计方差 聚合函数对一组值执行计算并返回单一的值。除COUNT函数之外,聚合函数忽略空值 (NULL)。聚合函数经常与SELECT语句的GROUP BY子句一同使用。所有聚合函数都具 有确定性。任何时候用一组给定的输入值调用它们时,都返回相同的值。 聚合函数仅在下列项中允许作为表达式使用: y SELECT语句的选择列表(子查询或外部查询) y COMPUTE或COMPUTE BY子句 y HAVING子句 例如,下面的SQL语句用来查询authors表中有几个作者的地址存在: USE bookdb GO SELECT COUNT(address) FROM authors GO 执行结果为: 2 而下面的SQL语句则是查询book表中书籍的价格的最大值: USE bookdb GO SELECT MAX(price) FROM book GO 执行结果为: 新概念 SQL Server 2005 教程 190 45 2. GROUP BY 子句 GROUP BY子句用来为结果集中的每一行产生聚合值。如果聚合函数没有使用GROUP BY子句,则只为SELECT语句报告一个聚合值。指定GROUP BY时,选择列表中任一非聚 合表达式内的所有列都应包含在GROUP BY列表中,或者GROUP BY表达式必须与选择列 表表达式完全匹配。 GROUP BY子句的语法格式为: [ GROUP BY [ ALL ] group_by_expression [ , …n ] [ WITH { CUBE | ROLLUP } ] ] 各参数含义如下: y ALL 包含所有组和结果集,甚至包含那些任何行都不满足WHERE子句指定的搜 索条件的组和结果集。如果指定了ALL,将对组中不满足搜索条件的汇总列返回 空值。不能用CUBE或ROLLUP运算符指定ALL。 y group_by_expression 是对其执行分组的表达式。group_by_expression也称为分组 列。group_by_expression可以是列或引用列的非聚合表达式。在选择列表内定义的 列的别名不能用于指定分组列。但是text、ntext和image类型的列不能用于 group_by_expression。 y CUBE 指定在结果集内不仅包含由GROUP BY提供的正常行,还包含汇总行。在 结果集内返回每个可能的组和子组组合的GROUP BY汇总行。GROUP BY汇总行 在结果中显示为NULL,但可用来表示所有值。使用GROUPING函数确定结果集内 的空值是否是GROUP BY汇总值。 提 示 结果集内的汇总行数取决于GROUP BY子句内包含的列数。GROUP BY子句中的每 个操作数(列)绑定在分组NULL下,并且分组适用于所有其他操作数(列)。由于CUBE 返回每个可能的组和子组组合,因此不论指定分组列时所使用的是什么顺序,行数都相同。 y ROLLUP 指定在结果集内不仅包含由GROUP BY提供的正常行,还包含汇总行。 按层次结构顺序,从组内的最低级别到最高级别汇总组。组的层次结构取决于指 定分组列时所使用的顺序。更改分组列的顺序会影响在结果集内生成的行数。 注 意 使用CUBE或ROLLUP 时,不支持区分聚合,如AVG(DISTINCT column_name)、 COUNT(DISTINCT column_name)和SUM(DISTINCT column_name)。如果使用这类聚合, SQL Server将返回错误信息并取消查询。 例如,下面的SQL语句首先在clients表、book表、orderform表中插入几笔记录,然后使 用GROUP BY子句汇总各个客户所订购的书籍总数: 191 第7章 Chapter 07 SQL高级使用 USE bookdb GO --在clients表中插入两个客户 INSERT clients VALUES(2,'科技书店','北京市朝阳区') INSERT clients VALUES(3,'明天书屋','北京市西城区') --GO --在book表中插入4本书的记录 INSERT book VALUES(5,2,'AutoCAD 2008 中文版使用指南',25.0,'21世纪出版社','') INSERT book VALUES(6,2,'Office 2007 中文版使用指南',28.0,'明天出版社','') INSERT book VALUES(7,1,'Windows Vista 中文版使用指南',30.0,'东东出版社','') INSERT book VALUES(8,3,'Linux 使用指南',32.0,'唐唐出版社','') GO --在orderform表中插入6笔记录 INSERT orderform VALUES(2,6,10,GETDATE(),2) INSERT orderform VALUES(3,5,10,GETDATE(),3) INSERT orderform VALUES(4,3,25,GETDATE(),1) INSERT orderform VALUES(5,8,15,GETDATE(),1) INSERT orderform VALUES(6,4,30,GETDATE(),3) INSERT orderform VALUES(7,7,40,GETDATE(),2) GO SELECT clients.client_name,SUM(orderform.book_number) AS 书籍总数 FROM clients,orderform WHERE clients.client_id=orderform.client_id GROUP BY clients.client_name GO 执行结果如下: client_name 书籍总数 ----------- ----------- 科技书店 50 刘明耀 90 明天书屋 40 CUBE参数会对检索的字段中各类型的数据做汇总运算。例如,下面的SQL语句就是使 用CUBE进行汇总的例子: SELECT clients.client_name,book.book_name, SUM(orderform.book_number) AS 书籍总数 FROM clients,orderform,book WHERE clients.client_id=orderform.client_id AND book.book_id= orderform.book_id GROUP BY clients.client_name,book.book_name WITH CUBE 执行结果如图7.1所示。 使用CUBE,可以计算client_name字段中“科技书店”、“刘明耀”和“明天书屋”及 其所有客户(以NULL表示)分别订购书的总量。还会统计book_name字段中各种书籍的订 购总量。 ROLLUP参数会依据GROUP BY后面所列第一个字段做汇总运算。如果要检索不同客 户订购的各种书的总量和所有书的总量,可执行下述SQL语句: SELECT clients.client_name,book.book_name, SUM(orderform.book_number) AS 书籍总数 新概念 SQL Server 2005 教程 192 FROM clients,orderform,book WHERE clients.client_id=orderform.client_id AND book.book_id= orderform.book_id GROUP BY clients.client_name,book.book_name WITH ROLLUP 执行结果如图7.2所示。 图 7.1 使用 CUBE 的汇总结果 图 7.2 使 ROLLUP 的汇总结果 3. HAVING 子句 HAVING子句指定组或聚合的搜索条件。HAVING通常与GROUP BY子句一起使用。 如果不使用GROUP BY子句,HAVING的行为与WHERE子句一样。但是聚合函数可以在 HAVING子句中使用,而不能在WHERE子句中使用。 HAVING子句的语法格式为: [HAVING ] 其中指定组或聚合应满足的搜索条件。当HAVING与GROUP BY ALL一起使用时,HAVING子句替代ALL。 注 意 在HAVING子句中不能使用text、image和ntext数据类型。另外,在SELECT语句中使 用HAVING子句不影响CUBE运算符分组结果集和返回汇总聚合行的方式。 科技书店订购的 各种书籍的数量 科技书店订购的 书籍总量 所有客户订购的 书籍总量 所有客户订购的 各种书籍的总量 193 第7章 Chapter 07 SQL高级使用 例如,下面的SQL语句用于查询订购书量大于等于40本的客户名称和书名: SELECT clients.client_name,book.book_name, SUM(orderform.book_number) AS 书籍总数 FROM clients,orderform,book WHERE clients.client_id=orderform.client_id AND book.book_id=orderform.book_id GROUP BY clients.client_name,book.book_name HAVING SUM(orderform.book_number)>=40 执行结果如下: client_name book_name 书籍总数 -------------- ---------------------------------------- --------- 刘明耀 3D Studio MAX实例精选 50 科技书店 Windows Vista 中文版使用指南 40 4. COMPUTE 和 COMPUTE BY 子句 SQL Server 2005提供COMPUTE和COMPUTE BY是为了保持向后兼容。如果不考虑兼 容的问题,则应使用SQL Server 2005 Analysis Services和用于Analysis Services的OLE DB或 多维的Microsoft ActiveX数据对象(ADO MD)或者ROLLUP运算符。 其语法格式为: [ COMPUTE { { AVG | COUNT | MAX | MIN | STDEV | STDEVP| VAR | VARP | SUM } ( expression ) } [ , …n ] [ BY expression [ , …n ] ] 各参数含义如下: y AVG | COUNT | MAX | MIN | STDEV | STDEVP| VAR | VARP | SUM 指定要使用 的聚合函数。如果没有,则等同于COUNT(*)函数 y expression 表达式,如对其执行计算的列名。expression必须出现在选择列表中, 并且必须将其指定为与选择列表中的某个表达式完全一样。在expression内不能使 用在选择列表中指定的列的别名。 y BY expression 在结果集内生成控制中断和分类汇总。expression 是 order_by_expression在相关ORDER BY子句中的精确副本。一般情况下,这是列名 或列的别名。可指定多个表达式。在BY后列出多个表达式可将一个组分成子组并 在每个分组级别上应用聚合函数。 如果使用COMPUTE BY,则必须也使用ORDER BY子句。表达式必须与在QRDER BY 后列出的子句相同或是其子集,并且必须按相同的序列。例如,如果ORDER BY子句是: ORDER BY a, b, c 则COMPUTE子句可以是下面的任意一个(或全部): COMPUTE BY a, b, c COMPUTE BY a, b COMPUTE BY a 新概念 SQL Server 2005 教程 194 使用COMPUTE BY子句可以用同一SELECT语句既查看明细行,又查看汇总行。可以 计算子组的汇总值,也可以计算整个结果集的汇总值。 COMPUTE子句需要下列信息: y 可选的BY关键字,该关键字可按对一列计算指定的行聚合。 y 行聚合函数名称,例如,SUM、AVG、MIN、MAX或COUNT。 y 要对其执行行聚合函数的列。 下面就是使用COMPUTE子句的例子: SELECT clients.client_name,book.book_name,order form.book_number FROM clients,orderform,book WHERE clients.client_id=orderform.client_id AND book.book_id= orderform.book_id COMPUTE SUM(orderform.book_number) 执行结果如图7.3所示。 如果需要各个客户的订购数量,而不是总的订购数量,则可执行下面的SQL语句: FROM clients,orderform,book WHERE clients.client_id=orderform.client_id AND book.book_id= orderform.book_id ORDER BY clients.client_name COMPUTE SUM(orderform.book_number) BY clients.client_name 执行结果如图7.4所示。 图 7.4 查询各个客户的订购数量 由上面的结果可看到,COMPUTE所生成的汇总值在查询结果中显示为分离的结果集。 包括COMPUTE子句的查询的结果类似于控制中断报表,即汇总值由指定的组(或称中断) 控制的报表。可以为各组生成汇总值,也可以对同一组计算多个聚合函数。 图 7.3 使用 COMPUTE 子句的执行结果 195 第7章 Chapter 07 SQL高级使用 当COMPUTE带有可选的BY子句时,符合SELECT条件的每个组都有两个结果集: y 每个组的第一个结果集是明细行集,其中包含该组的选择列表信息。 y 每个组的第二个结果集有一行,其中包含该组的COMPUTE子句中所指定的聚合函 数的小计。 当COMPUTE不带可选的BY子句时,SELECT语句有两个结果集: y 每个组的第一个结果集是包含选择列表信息的所有明细行。 y 每个组的第二个结果集有一行,其中包含COMPUTE子句中所指定的聚合函数的合 计。 5. COMPUTE 和 GROUP BY 的区别 COMPUTE和GROUP BY之间的区别汇总如下: y GROUP BY生成单个结果集。每个组都有一个只包含分组依据列和显示该组子聚 合的聚合函数的行。选择列表只能包含分组依据列和聚合函数。 y COMPUTE生成多个结果集。一类结果集包含每个组的明细行,其中包含选择列表 中的表达式。另一类结果集包含组的子聚合,或SELECT语句的总聚合。选择列表 可包含除分组依据列或聚合函数之外的其他表达式。聚合函数在COMPUTE子句中 指定,而不是在选择列表中。 7.1.2 联接查询 通过联接,可以根据各个表之间的逻辑关系从两个或多个表中检索数据。联接表示SQL Server 2005应如何使用一个表中的数据来选择另一个表中的行。 联接条件通过以下方法定义两个表在查询中的关联方式: y 指定每个表中要用于联接的列。典型的联接条件在一个表中指定外键,在另一个 表中指定与其关联的键。 y 指定比较各列的值时要使用的逻辑运算符(=、<>等)。 可在FROM或WHERE子句中指定联接。联接条件与WHERE和HAVING搜索条件组合, 用于控制FROM子句引用的基表中所选定的行。 在FROM子句中指定联接条件有助于将这些联接条件与WHERE子句中可能指定的其 他搜索条件分开,指定联接时建议使用这种方法。简单的子句联接语法如下: FROM first_table join_type second_table [ON (join_condition)] 其中join_type指定所执行的联接类型,包括内联接、外联接或交叉联接。join_condition 定义要为每对联接的行选取的谓词。 例如,下面使用联接查询书的名称及书的作者: USE bookdb GO SELECT book_name,author_name FROM book JOIN authors ON (book.author_id=authors.author_id) 新概念 SQL Server 2005 教程 196 GO 执行结果如下: book_name author_name ---------------------------------------- --------------- Windows Vista看图速成 刘耀儒 3D Studio MAX实例精选 王晓明 Windows 2003 Server网络管理 刘耀儒 Mathematica 5.0入门与提高 刘耀儒 AutoCAD 2008 中文版使用指南 王晓明 Office 2007 中文版使用指南 王晓明 Windows Vista 中文版使用指南 刘耀儒 Linux 使用指南 张英魁 提 示 当单个查询引用多个表时,所有列引用都必须明确。在查询所引用的两个或多个表 之间,任何重复的列名都必须用表名限定。如果某个列名在查询用到的两个或多个表中不 重复,则对这一列的引用不必用表名限定。但是,如果所有的列都用表名限定,则能提高 查询的可读性。如果使用表的别名,则会进一步提高可读性,特别是在表名自身必须由数 据库和所有者名称限定时。 虽然联接条件通常使用相等比较(=),但也可以像指定其他谓词一样指定其他比较或 关系运算符。 SQL Server处理联接时,查询引擎从多种可能的方法中选择最高效的方法处理联接。 尽管不同联接的物理执行采用多种不同的优化,但是逻辑序列都应用: y FROM子句中的联接条件; y WHERE子句中的联接条件和搜索条件; y HAVING子句中的搜索条件。 如果在FROM和WHERE子句间移动条件,则这个序列有时会影响查询结果。 联接条件中用到的列不必具有相同的名称或相同的数据类型。但是如果数据类型不相 同,则必须兼容或可由SQL Server进行隐性转换。如果不能隐性转换数据类型,则联接条 件必须用CAST函数显式地转换数据类型。 无法在ntext、text或image列上直接联接表。不过,可以用SUBSTRING在ntext、text或 image列上间接联接表。例如: SELECT * FROM t1 JOIN t2 ON SUBSTRING(t1.textcolumn, 1, 20) = SUBSTRING(t2.textcolumn, 1, 20) 在表t1和t2中的每个文本列前20个字符上进行两表内联接。此外,另一种比较两个表中 的ntext或text列的方法是用WHERE子句比较列的长度。例如: WHERE DATALENGTH(p1.pr_info) = DATALENGTH(p2.pr_info) 1. 内联接 内联接是用比较运算符比较要联接列的值的联接。在SQL-92标准中,内联接可在 197 第7章 Chapter 07 SQL高级使用 FROM或WHERE子句中指定。这是WHERE子句中唯一一种SQL-92支持的联接类型。 WHERE子句中指定的内联接称为旧式内联接。 内联接使用INNER JOIN关键词,上面查询书的名称及书的作者的例子就是一个内联接 的例子,也可以按下面方式查询: USE bookdb GO SELECT book_name,author_name FROM book INNER JOIN authors ON (book.author_id=authors.author_id) GO 执行结果同上。 提 示 两个表或者多个表要做联接,一般来说,这些表之间存在着主键和外键的关系。所 以将这些键的关系列出,就可以得到表的联接结果。 2. 外联接 仅当至少有一个同属于两表的行符合联接条件时,内联接才返回行。内联接消除与另 一个表中的任何行不匹配的行。而外联接会返回FROM子句中提到的至少一个表或视图的 所有行,只要这些行符合任何WHERE或HAVING搜索条件。将检索通过左向外联接引用的 左表的所有行,以及通过右向外联接引用的右表的所有行。完整外部联接中两个表的所有 行都将返回。 SQL Server 2005对在FROM子句中指定的外联接使用以下关键字: y LEFT OUTER JOIN或LEFT JOIN(左向外联接) y RIGHT OUTER JOIN或RIGHT JOIN(右向外联接) y FULL OUTER JOIN或FULL JOIN(完整外部联接) (1)左向外联接 包括第一个命名表(“左”表,出现在 JOIN 子句的最左边)中的所有行。不包括右 表中的不匹配行。 例如,下面的SQL语句首先删除order_id为7的订单(订购的书籍为《Windows Vista中 文版使用指南》),然后查询哪本书没有被订购: USE bookdb GO DELETE orderform WHERE order_id=7 GO SELECT orderform.order_date,book.book_name, orderform.book_number FROM book LEFT OUTER JOIN orderform ON (book.book_id=orderform.book_id) GO 执行结果如图7.5所示。 新概念 SQL Server 2005 教程 198 图 7.5 查询没有被订购的书 由于前面删除了order_id为7的订单,该订单订购了《Windows Vista中文版使用指南》 一书,所以在上面的检索中,由于使用了左向外联接,所以造成检索结果中包含了book表 中的所有记录,而且《Windows Vista中文版使用指南》一书所在的记录中,order_date和 book_number两个字段的值为NULL。 (2)右向外联接 包括第二个命名表(“右”表,出现在JOIN子句的最右边)中的所有行。不包括左表 中的不匹配行。 实际上,右向外联接和左向外联接的功能是一样的,例如,在上面的示例中,将FROM 子句中book表和orderform表交换一下位置,然后使用RIGHT OUTER JOIN: USE bookdb GO SELECT orderform.order_date,book.book_name, orderform.book_number FROM orderform RIGHT OUTER JOIN book ON (book.book_id=orderform.book_id) GO 执行结果和上面相同。 (3)完整外部联接 若要通过在联接结果中包括不匹配的行保留不匹配信息,可以使用完整外部联接。SQL Server 2005提供完整外部联接运算符FULL OUTER JOIN,不管另一个表是否有匹配的值, 此运算符都包括两个表中的所有行。 3. 交叉联接 在这类联接的结果集内,两个表中每两个可能成对的行占一行。交叉联接不使用 WHERE子句。在数学上,就是表的笛卡儿积。第一个表的行数乘以第二个表的行数等于笛 卡尔积结果集的大小。 例如,下面的SQL语句使用交叉联接产生客户和作者可能的组合: USE bookdb GO SELECT clients.client_name,authors.author_name FROM clients CROSS JOIN authors GO 执行结果如下: 199 第7章 Chapter 07 SQL高级使用 client_name author_name ---------- ---------------- 刘明耀 刘耀儒 科技书店 刘耀儒 明天书屋 刘耀儒 刘明耀 王晓明 科技书店 王晓明 明天书屋 王晓明 刘明耀 张英魁 科技书店 张英魁 明天书屋 张英魁 提 示 交叉联接产生的结果集一般是毫无意义的,但在数据库的数学模式上却有着重要的 作用。 7.1.3 子查询 子查询是一个SELECT查询,它返回单个值且嵌套在SELECT、INSERT、UPDATE、 DELETE语句或其他子查询中。任何允许使用表达式的地方都可以使用子查询。子查询也 称为内部查询或内部选择,而包含子查询的语句也称为外部查询或外部选择。 子查询能够将比较复杂的查询分解为几个简单的查询。而且子查询可以嵌套,嵌套查 询的过程是:首先执行内部查询,它查询出来的数据并不被显示出来,而是传递给外层语 句,并作为外层语句的查询条件来使用。 嵌套在外部SELECT语句中的子查询包括以下组件: y 包含标准选择列表组件的标准SELECT查询; y 包含一个或多个表或者视图名的标准FROM子句; y 可选的WHERE子句; y 可选的GROUP BY子句; y 可选的HAVING子句。 子查询的SELECT查询总是用圆括号括起来。且不能包括COMPUTE或FOR BROWSE 子句,如果同时指定TOP子句,则可能只包括ORDER BY子句。 子查询可以嵌套在外部SELECT、INSERT、UPDATE或DELETE语句WHERE或 HAVING子句内,或者其他子查询中。尽管根据可用内存和查询中其他表达式的复杂程度 不同,嵌套限制也有所不同,但一般均可以嵌套到32层。个别查询可能会不支持32层嵌套。 任何可以使用表达式的地方都可以使用子查询,只要它返回的是单个值。 例如,下面的SQL语句使用子查询来查询《Windows 2003 Server网络管理》一书的作 者: USE bookdb GO SELECT author_name FROM authors WHERE author_id = (SELECT author_id 新概念 SQL Server 2005 教程 200 FROM book WHERE book_name='Windows 2003 Server网络管理') GO 使用下面的联接方式也能完成此功能: USE bookdb GO SELECT author_name FROM authors JOIN book ON(book.author_id=authors.author_id) WHERE book_name='Windows 2003 Server网络管理' GO 执行结果均为: author_id -------------- 刘耀儒 在Transact-SQL中,包括子查询的语句和不包括子查询但语义上等效的语句在性能方 面通常没有区别。但是,在一些必须检查存在性的情况中,使用联接会产生更好的性能。 否则,为确保消除重复值,必须为外部查询的每个结果都处理嵌套查询。所以在这些情况 下,联接方式会产生更好的效果。 注 意 如果某个表只出现在子查询中而不出现在外部查询中,那么该表中的列就无法包含 在输出中(外部查询的选择列表)。 在某些Transact-SQL语句中,子查询可以像一个独立的查询一样进行评估。从概念上 讲,子查询结果将代入外部查询中(尽管不必知道SQL Server实际上如何通过子查询处理 Transact-SQL语句)。 有3种常用的子查询。它们是: y 在通过IN引入的列表或者由ANY或ALL修改的比较运算符的列表上进行操作。 y 通过无修改的比较运算符引入,并且必须返回单个值。 y 通过EXISTS引入的存在测试。 上述3种自查询通常采用的格式有下面几种: y WHERE expression [NOT] IN (subquery); y WHERE expression comparison_operator [ANY | ALL] (subquery); y WHERE [NOT] EXISTS (subquery)。 1. 子查询规则 在SQL Server 2005中,由于子查询也是使用SELECT语句组成,所以在SELECT语句应 注意的问题,在这里也适用。除此以外,子查询还要受下面的条件限制: y 通过比较运算符引入的子查询的选择列表只能包括一个表达式或列名称(分别对 SELECT * 或列表进行EXISTS和IN操作除外)。 201 第7章 Chapter 07 SQL高级使用 y 如果外部查询的WHERE子句包括某个列名,则该子句必须与子查询选择列表中的 该列在联接上兼容。 y 子查询的选择列表中不允许出现ntext、text和image数据类型。 y 由于必须返回单个值,所以由无修改的比较运算符(指其后未接关键字ANY或 ALL)引入的子查询不能包括GROUP BY和HAVING子句。 y 包括GROUP BY的子查询不能使用DISTINCT关键字。 y 不能指定COMPUTE和INTO子句。 y 只有同时指定了TOP,才可以指定ORDER BY。 y 由子查询创建的视图不能更新。 y 按约定,通过EXISTS引入的子查询的选择列表由星号(*)组成,而不使用单个 列名。由于通过EXISTS引入的子查询进行了存在测试,并返回TRUE或FALSE而 非数据,所以这些子查询的规则与标准选择列表的规则完全相同。 2. 子查询类型 可以在许多地方指定子查询,例如: y 使用别名时。 y 使用IN或NOT IN时。 y 在UPDATE、DELETE和INSERT语句中。 y 使用比较运算符时。 y 使用ANY、SOME或ALL时。 y 使用EXISTS或NOT EXISTS时。 y 在有表达式的地方。 下面将就这几种情况对子查询进行介绍。 (1)使用IN或NOT IN 通过IN(或NOT IN)引入的子查询结果是一列零值或更多值。子查询返回结果之后, 外部查询将利用这些结果。 例如,下面的SQL语句查询已经被订购的书的名称和出版社: USE bookdb GO SELECT book_name,publisher FROM book WHERE book_id IN( SELECT book_id FROM orderform) GO 执行结果为: book_name publisher -------------------------------------- ------------------------ 3D Studio MAX实例精选 明耀工作室 Windows 2003 Server网络管理 唐唐出版社 新概念 SQL Server 2005 教程 202 Mathematica 5.0入门与提高 东东出版社 AutoCAD 2008 中文版使用指南 21世纪出版社 Office 2007 中文版使用指南 明天出版社 Linux 使用指南 唐唐出版社 上述语句的执行过程为:首先内部查询返回orderform表中的book_id,然后,这些值被 代入外部查询中,在book表中查找与上述标识号相配的书名。 如果要查询没有被订购的书籍,则可以使用NOT IN: USE bookdb GO SELECT book_name,publisher FROM book WHERE book_id NOT IN( SELECT book_id FROM orderform) GO 执行结果为: book_name publisher ------------------------------------ ----------------------- Windows Vista 中文版使用指南 东东出版社 提 示 使用联接而不使用子查询处理该问题及类似问题的一个不同之处在于,联接可以在 结果中显示多个表中的列,而子查询却不可以。 (2)UPDATE、DELETE和INSERT语句中的子查询 子查询可以嵌套在UPDATE、DELETE和INSERT语句以及SELECT语句中。例如,删 除没有被订购的书籍信息: USE bookdb GO DELETE book WHERE book_id NOT IN( SELECT book_id FROM orderform) GO SELECT * FROM book GO 执行结果为: book_id author_id book_name price publisher 简介 ------- ---------- -------- --------------- ------ --------- ------ 2 2 3D Studio MAX实例精选 35 明耀工作室 NULL 3 1 Windows 2003 Server网络管理 45 唐唐出版社 NULL 4 1 Mathematica 5.0入门与提高 30 东东出版社 NULL 5 2 AutoCAD 2008 中文版使用指南 25 21世纪出版社 6 2 Office 2007 中文版使用指南 28 明天出版社 8 3 Linux 使用指南 32 唐唐出版社 203 第7章 Chapter 07 SQL高级使用 可以看到,《Windows Vista中文版使用指南》一书已经被删除了。 (3)比较运算符的子查询 子查询可由一个比较运算符(=、<>、>、>=、<、!>,!<或<=)引入。与使用IN引入 的子查询一样,由未修改的比较运算符(后面不跟ANY或ALL的比较运算符)引入的子查 询必须返回单个值而不是值列表。如果这样的子查询返回多个值,SQL Server将显示错误 信息。 例如,下面查找大于平均价格的书籍: USE bookdb GO SELECT DISTINCT book.book_name FROM book WHERE price > (SELECT AVG(price) FROM book) GO 执行结果为: book_name ------------------------------------- 3D Studio MAX实例精选 Windows 2003 Server网络管理 可以用ALL或ANY关键字修改引入子查询的比较运算符。 以>比较运算符为例,>ALL表示大于每一个值,换句话说,大于最大值。例如,>ALL(1, 2, 3)表示大于3。>ANY表示至少大于一个值,也就是大于最小值。因此>ANY (1, 2, 3)表示 大于1。 要使带有>ALL的子查询中的某行满足外部查询中指定的条件,引入子查询的列中的值 必须大于由子查询返回的值的列表中的每个值。 同样,>ANY表示要使某一行满足外部查询中指定的条件,引入子查询的列中的值至 少大于由子查询返回的值的列表中的一个值。 例如,下面返回价格最高的一本书的书名: USE bookdb GO SELECT book.book_name FROM book WHERE price >=ALL (SELECT price FROM book) GO 执行结果为: book_name ----------------------------------------------- Windows 2003 Server网络管理 新概念 SQL Server 2005 教程 204 提 示 NOT IN运算符和<>ALL等效。 (4)存在性检查 存在性检查是通过EXISTS关键字来实现的,使用EXISTS引入的子查询语法如下: WHERE[NOT]EXISTS(subquery) 例如,要查询所有被订购的书籍名称及其相应的出版社,可使用下面的SQL语句: USE bookdb GO SELECT book_name,publisher FROM book WHERE EXISTS( SELECT * FROM orderform) GO 执行结果为: book_name publisher ------------------------------------------- ---------------------- 3D Studio MAX实例精选 明耀工作室 Windows 2003 Server网络管理 唐唐出版社 Mathematica 5.0入门与提高 东东出版社 AutoCAD 2008 中文版使用指南 21世纪出版社 Office 2007 中文版使用指南 明天出版社 Linux 使用指南 唐唐出版社 使用EXISTS引入的子查询在以下几方面与其他子查询略有不同: y EXISTS关键字前面没有列名、常量或其他表达式。 y 由EXISTS引入的子查询的选择列表通常几乎都是由星号(*)组成。由于只是测 试是否存在符合子查询中指定条件的行,所以不必列出列名。 3. 多层嵌套 子查询自身可以包括一个或多个子查询。一个语句中可以嵌套任意数量的子查询,这 便是多层嵌套。 例如,下面使用多层嵌套子查询来查询客户“科技书店”所订购的书籍名称: USE bookdb GO SELECT book_name FROM book WHERE book_id IN( SELECT book_id FROM orderform WHERE client_id=( SELECT client_id 205 第7章 Chapter 07 SQL高级使用 FROM clients WHERE client_name='科技书店') ) GO 执行结果如下: book_name ----------------------------------------------------------------------- Office 2007 中文版使用指南 4. 相关子查询 如果子查询的WHERE子句引用外部查询表,则该查询称为相关子查询(Correleted Subquery),也称为重复查询。 例如,下面使用相关子查询查询名为“刘耀儒”的作者所著的书目: USE bookdb GO SELECT book_name FROM book WHERE '刘耀儒' IN (SELECT author_name FROM authors WHERE authors.author_id = book.author_id) GO 执行结果为: book_name ----------------------------------------------------------- Windows 2003 Server网络管理 Mathematica 5.0入门与提高 相关查询的执行过程如下: 子查询为外部查询的每一行执行一次,即外部查询将相关的列值传给内部查询。 如果子查询的任何行与其匹配,外部查询就返回结果行。 再回到第一步,直到处理完外部表的所有行。 7.1.4 使用UNION运算符组合多个结果 使用UNION运算符可以将两个或多个SELECT语句的结果组合成一个结果集。使用 UNION组合的结果集都必须具有相同的结构。而且它们的列数必须相同,并且相应的结果 集列的数据类型必须兼容。 例如,要查询所有作者和客户的号码和名称,可使用下面的SQL语句: USE bookdb GO SELECT author_id,author_name FROM authors UNION SELECT client_id,client_name FROM clients GO 新概念 SQL Server 2005 教程 206 执行结果为: author_id author_name ----------- -------------------- 1 刘明耀 1 刘耀儒 2 科技书店 2 王晓明 3 明天书屋 3 张英魁 UNION的结果集列名与UNION运算符中第一个SELECT语句的结果集中的列名相同。 另一个SELECT语句的结果集列名将被忽略。 提 示 默认情况下,SQL Server 2005从左到右对包含UNION运算符的语句进行取值。但是 可以使用圆括号指定求值的顺序。 7.1.5 在查询的基础上创建新表 使用INTO关键字可以创建新表并将结果行从查询插入新表中。 例如,下面的SQL语句将查询得到的书名和作者插入到新建的表author_book中: USE bookdb GO SELECT book.book_name,authors.author_name INTO author_book FROM authors,book WHERE authors.author_id=book.author_id GO 执行结果可通过下面的SELECT语句来查看: SELECT * FROM author_book 注 意 用户若要执行带INTO子句的SELECT语句,必须在目的数据库内具有CREATE TABLE权限。SELECT…INTO不能与COMPUTE子句一起使用。 在SQL Server 2005中,select into/bulkcopy数据库选项对是否可以使用SELECT INTO创 建永久表没有影响。对包括SELECT INTO在内的某些大容量操作的记录量,取决于对数据 库有效的恢复模式。 7.2 错误处理 在SQL Server 2005中出现的错误具有以下几个特性: y 错误号 每个错误状态都对应唯一的错误号。 207 第7章 Chapter 07 SQL高级使用 y 错误信息字符串 错误信息提供了有关错误原因的诊断信息。许多错误信息都有 替换变量,其中包含一些信息,如产生错误的对象名称。每个错误号都对应唯一 的错误信息。 y 严重度 严重度表示错误的严重程度。严重度较低的错误,如1级或2级,为信息 性消息或低级警告。严重度较高的错误表明问题需要尽快解决。 y 状态代码 一些错误代码可能在SQL Server源代码中多处出现。例如,几种不同情 况下都可能发生1105错误。出现错误代码的每一处都指派了唯一的状态代码。可 以使用错误的状态代码在源代码中查找错误代码的位置,这可以为问题的诊断提 供参考。 y 过程名 如果在存储过程中发生错误,则该存储过程的名称也许可用。 y 行号 行号指出存储过程中产生错误的语句。 SQL Server的所有错误都存储在系统表master.dbo.sysmessages中。用户定义的消息也可 以存储在sysmessages中。如果需要,可以使用RAISERROR语句将这些用户定义的错误返 回到一个应用程序。 所有的数据库API,如ADO、OLE DB、ODBC、DB-Library和嵌入式SQL,均报告基 本的错误属性:错误号和消息字符串。然而,每个数据库所能报告的其他错误特性的数量 是不同的。 7.2.1 使用@@ERROR全局变量处理错误 @@ERROR全局变量返回最后执行的Transact-SQL语句的错误代码。当SQL Server完成 Transact-SQL语句的执行时,如果语句执行成功,则@@ERROR设置为0。若出现一个错误, 则返回一条错误信息。@@ERROR返回此错误信息代码,直到另一条Transact-SQL语句被 执行。 注 意 由于@@ERROR在每一条语句执行后被清除并且重置,应在语句验证后立即检查它, 或将其保存到一个局部变量中以备事后查看。 在SQL Server中,可以使用下面两种方法对@@ERROR进行处理: y 在Transact-SQL语句后,马上检测或使用@@ERROR。 y 在Transact-SQL语句完成后,马上把@@ERROR存储到一个整型变量中。 例如,下述语句就是一个使用@@ERROR的例子: USE bookdb GO SELECT * FROM book GO IF @@ERROR=0 PRINT '执行成功!' GO 执行上述语句,则在“结果”窗口中显示查询结果,而在“消息”窗口中显示“执行 新概念 SQL Server 2005 教程 208 成功!”的字样。 7.2.2 使用RAISERROR 在上面的操作中,使用PRINT可以显示一些提示信息。与PRINT相比,RAISERROR在 把消息返回给应用程序方面的功能更强大。RAISERROR能以下列方式中的任意一种返回消 息: y 已通过sp_addmessage系统存储过程添加到master.dbo.sysmessages上的由用户定义 的错误信息。 y 在RAISERROR语句中指定的消息字符串。 除此以外,它还具有PRINT功能的一些扩展: y RAISERROR能够指派一个特定的错误号、严重度和状态。 y RAISERROR能够请求将错误记入SQL Server 2005错误日志和Windows应用程序 日志中。 y 消息字符串可以包含替代变量和参量,这与C语言中的printf功能相似。 当RAISERROR在sysmessages中与用户定义消息的msg_id一同使用时,msg_id被作为 SQL Server的错误号码或本机错误代码返回。而当RAISERROR与msg_str而不是 msg_id一 同使用时,返回的SQL Server的错误号和本机错误号为50 000。 例如,下面的例子在返回给应用程序的消息中替换了DB_ID和DB_NAME函数的值: DECLARE @DBID INT SET @DBID = DB_ID() DECLARE @DBNAME NVARCHAR(128) SET @DBNAME = DB_NAME() RAISERROR ('The current database ID is:%d, the database name is: %s.', 16, 1, @DBID, @DBNAME) 执行结果为: 消息50000,级别16,状态1,第7 行 The current database ID is:6, the database name is: AdventureWorks. 而以下例子使用由用户定义的消息完成了同样的处理: EXEC sp_addmessage 50005, 16, 'The current database ID is:%d, the database name is: %s.','us_english' GO DECLARE @DBID INT SET @DBID = DB_ID() DECLARE @DBNAME NVARCHAR(128) SET @DBNAME = DB_NAME() RAISERROR (50005, 16, 1, @DBID, @DBNAME) 209 第7章 Chapter 07 SQL高级使用 GO 执行结果为: 消息50005,级别16,状态1,第7 行 The current database ID is:6, the database name is: AdventureWorks. 上面的例子显示,替换参数可以在由用户定义的错误中指定,并且当RAISERROR语句 执行时由替换参变量填充。 7.3 管理ntext、text和image数据 SQL Server的ntext、text和image数据类型在单个值中可以包含非常大的数据量(最大 可达2GB)。单个数据值通常比应用程序在一个步骤中能够检索的大;某些值可能还会大 于客户端的可用虚拟内存。因此,在检索这些值时,通常需要一些特殊的步骤。 如果ntext、text和image数据值不超过Unicode串、字符串或二进制串的长度(分别为4 000 个字符、8 000个字符和8 000个字节),就可以在SELECT、UPDATE和INSERT语句中引用 它们,其引用方式与较小的数据类型相同。 例如,包含短值的ntext列可以在SELECT语句的选择列表中引用,这与nvarchar列的引 用方式相同。引用时必须遵守一些限制,例如不能在WHERE子句中直接引用ntext、text或 image列。这些列可以作为返回其他数据类型(例如ISNULL、SUBSTRING或PATINDEX) 的某个函数的参数包含在WHERE子句中,也可以包含在IS NULL、IS NOT NULL或LIKE 表达式中。 但是,如果ntext、text和image数据值较大,则必须逐块处理。Transact-SQL和数据库 API均包含使应用程序可以逐块处理ntext、text和image数据的函数。 数据库API按照一种通用的模式处理长ntext、text和image列: y 若要读取一个长列,应用程序只需在选择列表中包含ntext、text或image列,并将 该列绑定到一个程序变量,该变量应足以容纳适当的数据块。然后,应用程序就 可以执行该语句,并使用API函数或方法将数据逐块检索到绑定的变量中。 y 若要写入一个长列,应用程序可使用参数标记(?)在相应位置代替ntext、text或 image列中的值,以执行INSERT或UPDATE语句。参数标记(对ADO而言则为参 数)被绑定到一个足以容纳数据块的程序变量上。应用程序进入循环,在循环中 先将下一组数据移到绑定的变量中,然后调用API函数或方法写入数据块。这一过 程将反复进行,直到整个数据值发送完毕。 在SQL Server 2005中,用户可以在表上启用text in row选项,以使该表能够在其数据行 中存储text、ntext或image数据。 如果要启用该选项,可以执行sp_tableoption存储过程,将text in row指定为选项名并将 on指定为选项值。BLOB(二进制大对象:text、ntext或image数据)行中可以存储的默认最 大大小为256字节,但是值的范围可以从24~7000。若要指定默认值以外的最大大小,可以 指定该范围内的整数作为选项值。 新概念 SQL Server 2005 教程 210 提 示 如果text、ntext或image字符串比行中所指定的限制或可用空间大,则将指针存储在 该行中。在行中存储BLOB字符串的条件仍然适用,但是数据行中必须有足够的空间容纳 指针。 例如,下面的SQL语句在test数据库中创建一个text1表,其中c2字段的数据类型为text, 并插入一笔记录: USE test GO CREATE TABLE text1 (c1 int, c2 text) EXEC sp_tableoption 'text1', 'text in row', 'on' INSERT text1 VALUES ('1', 'This is a text.') GO 然后执行下面的SQL语句: SELECT * FROM text1 执行结果为: c1 c2 ------ ---------------- 1 This is a text. 7.3.1 检索ntext、text或image值 可以通过下面的方式来检索ntext、text或image值: y 在SELECT语句中引用该列。 y 使用TEXTPTR函数可获得传递给READTEXT语句的文本指针。 y 使用SUBSTRING函数可检索从列开头特定偏移位置开始的数据块。 y 使用PATINDEX函数可检索一些特定字节组合的偏移量。 1. 在 SELECT 语句中引用该列 这是在使用API(例如ADO、OLE DB、ODBC或DB-Library)的数据库应用程序中所 使用的方法。该列被绑定到一个程序变量上,然后使用特殊的API函数或方法逐块检索数据。 如果在Transact-SQL脚本、存储过程和触发器中使用这种方法,则只能用于相对较短 的值。如果数据的长度大于SET TEXTSIZE中指定的长度,则必须增大TEXTSIZE或使用其 他方法。当前的TEXTSIZE设置通过@@TEXTSIZE函数报告,默认设置为4096(4 KB)。 并可使用SET TEXTSIZE语句进行更改。 例如,可使用下面的语句将TEXTSIZE改为64 512: SET TEXTSIZE 64 512 如果要改为默认值,则可以使用下面的SQL语句: SET TEXTSIZE 0 211 第7章 Chapter 07 SQL高级使用 2. 使用 TEXTPTR 函数可获得传递给 READTEXT 语句的文本指针 READTEXT 语句用于读取ntext、text或image数据块。其语法格式为: READTEXT { table.column text_ptr offset size } [ HOLDLOCK ] 其中各参数含义为: y table.column 是从中读取的表和列的名称。表名和列名必须符合标识符的规则。 必须指定表名和列名,不过可以选择是否指定数据库名称和所有者名称。 y text_ptr 有效文本指针。text_ptr的数据类型必须是binary(16)。 y offset 开始读取text、image或ntext数据之前跳过的字节数(使用text或image数据 类型时)或字符数(使用ntext数据类型时)。使用ntext数据类型时,offset是在开 始读取数据前跳过的字符数。使用text或image数据类型时,offset是在开始读取数 据前跳过的字节数。 y size 是要读取数据的字节数(使用text或image数据类型时)或字符数(使用ntext 数据类型时)。如果size是0,则表示读取了4KB字节的数据。 y HOLDLOCK 使文本值一直锁定到事务结束。其他用户可以读取该值,但是不能 对其进行修改。 例如,下面读取text1表的c2字段的第1到第7个字符: --在对text数据类型的对象使用指针前,应将text in row选项关闭 EXEC sp_tableoption 'text1', 'text in row', 'off' DECLARE @ptrval varbinary(16) SELECT @ptrval = TEXTPTR(c2) FROM text1 READTEXT text1.c2 @ptrval 0 7 执行结果为: c2 ---------- This is 3. 使用 SUBSTRING 函数可检索从列开头特定偏移位置开始的数据块 SUBSTRING函数的语法格式如下: SUBSTRING ( expression , start , length ) 其中各参数含义如下: y expression 是字符串、二进制字符串、text、image、列或包含列的表达式。不要 使用包含聚合函数的表达式。 y start 是一个整数,指定子串的开始位置。 y length 是一个整数,指定子串的长度(要返回的字符数或字节数)。 例如,可以使用下面的SQL语句来检索text1表的c2字段的第1到第7个字符: SELECT SUBSTRING(c2, 1, 7) AS c2 新概念 SQL Server 2005 教程 212 FROM text1 执行结果为: c2 ---------- This is 提 示 由于在text数据上使用SUBSTRING时start和length指定字节数,因此DBCS数据(如 日本汉字)可能导致在结果的开始或结束位置拆分字符。此行为与READTEXT处理DBCS 的方式一致。然而,由于偶而会出现奇怪的结果,建议对DBCS字符使用ntext而非text。 如果expression是支持的字符数据类型,则SUBSTRING函数返回字符数据。如果 expression是支持的binary数据类型,则返回二进制数据。给定表达式和返回类型的关系如 表7.2所示。 表7.2 给定表达式和返回类型的关系 给定的表达式 返回类型 Text varchar Image varbinary Ntext nvarchar 4. 使用 PATINDEX 函数可检索一些特定字节组合的偏移量 PATINDEX函数返回指定表达式中某模式第一次出现的起始位置;如果在全部有效的 文本和字符数据类型中没有找到该模式,则返回零。 其语法格式为: PATINDEX ( '%pattern%' , expression ) 其各参数含义如下: y pattern 一个字符串,可以使用通配符,但pattern之前和之后必须有%字符(搜索 第一个和最后一个字符时除外)。pattern是短字符数据类型类别的表达式。 y expression 一个表达式,通常为要在其中搜索指定模式的列,expression为字符串 数据类型类别。 例如,下面的SQL语句检索字符a位于c2字段的第几个: USE test GO SELECT PATINDEX('%a%',c2) AS 起始位置 FROM text1 GO 执行结果如下: 起始位置 ------------- 9 213 第7章 Chapter 07 SQL高级使用 7.3.2 修改ntext、text或image值 可以使用下面的几种方式来修改ntext、text或image值。 1. 使用数据库 API 函数 使用数据库API(例如ADO、OLE DB或ODBC)执 行 UPDATE或INSERT语句并将程序 变量与ntext、text或image列的参数标记绑定。然后调用相应的数据库API函数,逐块向数据 库发送长数据。DB-Library支持与其text和image函数相同的功能。 2. 使用 WRITETEXT 语句重写该列的整个数据值 WRITETEXT语句允许对现有的text、ntext或image列进行无日志记录的交互式更新。 该语句将彻底重写受其影响的列中的任何现有数据。其语法格式为: WRITETEXT { table.column text_ptr }[ WITH LOG ] { data } 其中各参数的含义为: y table.column 要更新的表和text、ntext或image列的名称。表名和列名必须符合标 识符的规则。 y text_ptr 指向text、ntext或image数据的指针的值。text_ptr的数据类型必须为 binary(16)。 y WITH LOG 在SQL Server 2005中忽略。日志记录由数据库的实际恢复模型决定。 y data 要存储的实际text、ntext或image数据。data可以是字面值,也可以是变量。 对于text、ntext和image数据,可以用WRITETEXT交互插入的文本的最大长度大约 是120KB。 例如,下面的SQL语句修改test数据库中的text1表的字符串值: USE test GO DECLARE @ptrval varbinary(16) SELECT @ptrval = TEXTPTR(c2) FROM text1 WRITETEXT text1.c2 @ptrval 'This is a modified text.' GO SELECT * FROM text1 GO 执行结果为: c1 c2 --- --------------------------- 1 This is a modified text. 注 意 WRITETEXT语句不能用在视图中的text、ntext和image列上。 3. 使用 UPDATETEXT 语句更新 ntext、text 或 image 列的特定数据块 使用UPDATETEXT语句可以更新现有text、ntext或image 字段列的一部分。其语法格 新概念 SQL Server 2005 教程 214 式如下: UPDATETEXT { table_name.dest_column_name dest_text_ptr } { NULL | insert_offset } { NULL | delete_length } [ WITH LOG ] [ inserted_data | { table_name.src_column_name src_text_ptr } ] 其中各参数含义如下: y table_name.dest_column_name 要更新的表和text、ntext或image列的名称。表名和 列名必须符合标识符的规则。 y dest_text_ptr 指向要更新的text、ntext或image数据的文本指针的值(由TEXTPTR 函数返回)。dest_text_ptr必须为binary(16)。 y insert_offset 以零为基的更新起始位置。对于text或image列,insert_offset是在插 入新数据前从现有列的起点开始要跳过的字节数;对于ntext列,insert_offset是字 符个数(每个ntext字符占用2个字节)。开始于这个以零为基的起始点的现有text、 ntext或image数据向右移,为新数据腾出空间。值为0表示将新数据插入到现有位 置的开始处。值为NULL则将新数据追加到现有数据值中。 y delete_length 是从insert_offset位置开始的、要从现有text、ntext或image列中删除 的数据长度。delete_length值对于text和image列用字节指定,对于ntext列用字符指 定。每个ntext字符占用2个字节。值为0表示不删除数据。值为NULL则删除现有text 或image列中从insert_offset位置开始到末尾的所有数据。 y WITH LOG 在SQL Server 2000中被忽略。但在SQL Server 2005中,日志记录由 数据库的有效恢复模型决定。 y inserted_data 是要插入到现有text、ntext或image列insert_offset位置的数据。这是 单个char、nchar、varchar、nvarchar、binary、varbinary、text、ntext或image值。 inserted_data可以是文字或变量。 y table_name.src_column_name 用作插入数据源的表或text、ntext或image列的名称。 表名和列名必须符合标识符的规则。 y src_text_ptr 指向作为插入数据源使用的text、ntext或image列的文本指针值(由 TEXTPTR函数返回)。该值不能和dest_text_ptr的值相同。 例如,下面的SQL语句在text1表的c2字段的末尾加入字符串This is an inserted text.: USE test GO DECLARE @ptrval varbinary(16) SELECT @ptrval = TEXTPTR(c2) FROM text1 UPDATETEXT text1.c2 @ptrval NULL 0 'This is an inserted text.' GO SELECT * FROM text1 GO 215 第7章 Chapter 07 SQL高级使用 执行结果为: c1 c2 --- --------------------------- 1 This isamodifiedtext.Thisisainsertedtext. 提 示 使用WRITETEXT来替换text、ntext和image数据,而用UPDATETEXT来修改text、ntext 和image数据。UPDATETEXT更灵活,因为它仅更改text、ntext或image列的某一部分,而 不是整个列。 7.4 事务处理 事务是SQL Server中的单个逻辑单元,一个事务内的所有SQL语句作为一个整体执行, 要么全部执行,要么都不执行。 一个逻辑工作单元必须有4个属性,称为ACID(原子性、一致性、隔离性和持久性) 属性,只有这样才能成为一个事务: y 原子性(Atomicity) 事务必须是原子工作单元。对于其数据修改,要么全都执 行,要么全都不执行。 y 一致性(Consistency) 事务在完成时,必须使所有的数据都保持一致状态。在 相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。 事务结束时,所有的内部数据结构(如B树索引或双向链表)都必须是正确的。 y 隔离性(Isolation) 由并发事务所做的修改必须与任何其他并发事务所做的修改 隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态, 要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串 行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的 状态与原始事务执行的状态相同。 y 持久性(Durability) 事务完成之后,它对于系统的影响是永久性的。该修改即 使出现系统故障也将一直保持。 7.4.1 事务分类 按事务的启动和执行方式,可以将事务分为3类: y 显示事务 也称为用户定义或用户指定的事务,即可以显式地定义启动和结束的 事务。分布式事务是一种特殊的显示事务,当数据库系统分布在不同的服务器上 时,要保证所有服务器的数据的一致性和完整性,就要用到分布式事务。 y 自动提交事务 自动提交模式是SQL Server 的默认事务管理模式。每个 Transact-SQL语句在完成时,都被提交或回滚。如果一个语句成功地完成,则提交 该语句;如果遇到错误,则回滚该语句。只要自动提交模式没有被显式或隐性事 务替代,SQL Server连接就以该默认模式进行操作。自动提交模式也是ADO、OLE 新概念 SQL Server 2005 教程 216 DB、ODBC和DB-Library的默认模式。 y 隐性事务 当连接以隐性事务模式进行操作时,SQL Server将在提交或回滚当前事 务后自动启动新事务。无须描述事务的开始,只须提交或回滚每个事务。隐性事 务模式生成连续的事务链。 7.4.2 显示事务 显示事务需要显示的定义事务的启动和结束。它是通过BEGIN TRANSACTION、 COMMIT TRANSACTION、COMMIT WORK、ROLLBACK TRANSACTION或ROLLBACK WORK等Transact-SQL语句来完成的。 1. 启动事务 启动事务使用BEGIN TRANSACTION语句,该语句将@@TRANCOUNT加1。其语法 格式如下: BEGIN TRAN [ SACTION ] [ transaction_name | @tran_name_variable [ WITH MARK [ 'description' ] ] ] 其中各参数含义如下: y transaction_name 是给事务分配的名称。transaction_name必须遵循标识符规则, 但是不允许标识符多于32个字符。仅在嵌套的BEGIN…COMMIT或BEGIN… ROLLBACK语句的最外语句对上使用事务名。 y @tran_name_variable 是用户定义的、含有有效事务名称的变量的名称。必须用 char、varchar、nchar或nvarchar 数据类型声明该变量。 y WITH MARK ['description'] 指定在日志中标记事务。description是描述该标记的 字符串。 注 意 如果使用了WITH MARK,则必须指定事务名。WITH MARK允许将事务日志还原到 命名标记。 BEGIN TRANSACTION代表一点,由连接引用的数据在该点是逻辑和物理上都一致 的。如果遇上错误,在BEGIN TRANSACTION之后的所有数据改动都能进行回滚,以将数 据返回到已知的一致状态。每个事务继续执行直到它无误地完成并且用COMMIT TRANSACTION 对数据库做永久的改动,或者遇上错误并且用ROLLBACK TRANSACTION语句擦除所有改动。 2. 结束事务 如果没有遇到错误,可使用COMMIT TRANSACTION语句成功地结束事务。该事务中 的所有数据修改在数据库中都将永久有效。事务占用的资源将被释放。 COMMIT TRANSACTION语句的语法格式如下: COMMIT [ TRAN [ SACTION ] [ transaction_name | @tran_name_variable ] ] 217 第7章 Chapter 07 SQL高级使用 其中各参数含义如下: y transaction_name SQL Server忽略该参数。transaction_name指定由前面的BEGIN TRANSACTION指派的事务名称。transaction_name必须遵循标识符的规则,但只 使用事务名称的前32个字符。通过向程序员指明COMMIT TRANSACTION与哪些 嵌套的BEGIN TRANSACTION相关联,transaction_name可作为帮助阅读程序代码 的一种方法。 y @tran_name_variable 是用户定义的、含有有效事务名称的变量的名称。必须用 char、varchar、nchar或nvarchar数据类型声明该变量。 也可以使用COMMIT WORK来结束事务,该语句没有参数。 3. 回滚事务 如果事务中出现错误,或者用户决定取消事务,可回滚该事务。回滚事务是通过 ROLLBACK语句来完成的。其语法格式如下: ROLLBACK [ TRAN [ SACTION ] [ transaction_name | @tran_name_variable | savepoint_name | @savepoint_variable ] ] 其中各参数含义为: y transaction_name 是在BEGIN TRANSACTION上的事务指派的名称。嵌套事务 时,transaction_name必须是来自最远的BEGIN TRANSACTION语句的名称。 y @tran_name_variable 是用户定义的、含有有效事务名称的变量的名称。 y savepoint_name 是来自SAVE TRANSACTION语句的savepoint_name。savepoint_ name 必须符合标识符规则。当条件回滚只影响事务的一部分时使用 savepoint_name。 y @savepoint_variable 是用户定义的、含有有效保存点名称的变量的名称。必须用 char、varchar、nchar或nvarchar数据类型声明该变量。 ROLLBACK TRANSACTION清除自事务的起点或到某个保存点所做的所有数据修 改。ROLLBACK还释放由事务控制的资源。 回滚事务也可以使用ROLLBACK WORK语句。. 注 意 在定义事务的时候,BEGIN TRANSACTION语句要和COMMIT TRANSACTION或者 ROLLBACK TRANSACTION语句成对出现。 4. 在事务内设置保存点 设置保存点使用SAVE TRANSACTION语句,其语法格式为: SAVE TRAN [ SACTION ] { savepoint_name | @savepoint_variable } 其中各参数含义为: 新概念 SQL Server 2005 教程 218 y savepoint_name 是指派给保存点的名称。保存点名称必须符合标识符规则,但只 使用前32个字符。 y @savepoint_variable 是用户定义的、含有有效保存点名称的变量的名称。必须用 char、varchar、nchar或nvarchar数据类型声明该变量。 用户可以在事务内设置保存点或标记。保存点是如果有条件地取消事务的一部分,事 务可以返回的位置。 例如: USE bookdb GO BEGIN TRAN MyTran --启动事务 INSERT INTO book VALUES(9,1,'Windows Vista看图速成',35,'21世纪出版社') --插入一笔记录 SAVE TRAN MySave --保存点 DELETE book WHERE book_id=9 --删除记录 ROLLBACK TRAN MySave --回滚事务 COMMIT TRAN GO SELECT * FROM book --查询book表的记录 GO 执行结果为: book_id author_id book_name price publisher 简介 ------- --------- ------------------------- ----- --------- ---- 2 2 3D Studio MAX实例精选 35 明耀工作室 NULL 3 1 Windows 2003 Server网络管理 45 唐唐出版社 NULL 4 1 Mathematica 5.0入门与提高 30 东东出版社 NULL 5 2 AutoCAD 2008 中文版使用指南 25 21世纪出版社 6 2 Office 2007 中文版使用指南 28 明天出版社 8 3 Linux 使用指南 32 唐唐出版社 9 1 Windows Vista看图速成 35 21世纪出版社 可以看到,上面的语句执行后,在book中插入了一笔记录,而并没有删除。这是因为 使用ROLLBACK TRAN MySave语句将操作回滚到了删除前的保存点处。 提 示 如果回滚到事务开始位置,则全局变量@@TRANCOUNT的值减去1。如果回滚到指 定的保存点,则全局变量@@TRANCOUNT的值不变。 5. 标记事务 WITH MARK选项使事务名置于事务日志中。将数据库还原到早期状态时,可使用标 记事务替代日期和时间。 另外,若要将一组相关数据库恢复到逻辑上一致的状态,必须使用事务日志标记。标 记可由分布式事务置于相关数据库的事务日志中。将这组相关数据库恢复到这些标记将产 219 第7章 Chapter 07 SQL高级使用 生一组在事务上一致的数据库。在相关数据库中放置标记需要特殊的过程。 6. 不能用于事务的操作 在事务处理中,并不是所有的Transact-SQL语句都可以取消执行,一些不能撤销的操 作,例如创建、删除和修改数据库的操作,即使SQL Server取消了事务执行或者对事务进 行了回滚,这些操作对数据库造成的影响也是不能恢复的。因此,这些操作不能用于事务 处理。这些操作如表7.3所示。 表7.3 不能用于事务的操作 操作 相应的 SQL 语句 创建数据库 CREATE DATABASE 修改数据库 ALTER DATABASE 删除数据库 DROP DATABASE 恢复数据库 RESTORE DATABASE 加载数据库 LOAD DATABASE 备份日志文件 BACKUP LOG 恢复日志文件 RESTORE LOG 更新统计数据 UPDATE STATITICS 授权操作 GRANT 复制事务日志 DUMP TRANSACTION 磁盘初始化 DISK INIT 更新使用 sp_configure 系统存储过程更改的配置选项的当前配置值 RECONFIGURE 7.4.3 自动提交事务 SQL Server使用BEGIN TRANSACTION语句启动显式事务,或隐性事务模式设置为打 开之前,将以自动提交模式进行操作。当提交或回滚显式事务或者关闭隐性事务模式时, SQL Server将返回到自动提交模式。 在自动提交模式下,有时看起来SQL Server好像回滚了整个批处理,而不是仅仅一个 SQL语句。这种情况只有在遇到的错误是编译错误而不是运行时错误时才会发生。编译错 误将阻止SQL Server建立执行计划,这样批处理中的任何语句都不会执行。尽管看起来好 像是产生错误之前的所有语句都被回滚了,但实际情况是该错误使批处理中的任何语句都 没有执行。 在下面的例子中,由于编译错误,第3个批处理中的任何INSERT语句都没有执行(没 有返回显示结果)。但看上去好像是前两个INSERT语句没有执行便进行了回滚: USE test GO CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3)) GO INSERT INTO TestBatch VALUES (1, 'aaa') INSERT INTO TestBatch VALUES (2, 'bbb') 新概念 SQL Server 2005 教程 220 INSERT INTO TestBatch VALUSE (3, 'ccc') /*符号错误*/ GO SELECT * FROM TestBatch /*不会返回任何结果*/ GO 7.4.4 隐式事务 在为连接将隐性事务模式设置为打开之后,当SQL Server首次执行某些Transact-SQL语 句时,都会自动启动一个事务,而不需要使用BEGIN TRANSACTION语句。这些 Transact-SQL语句包括: ALTER TABLE INSERT OPEN CREATE DELETE REVOKE DROP SELECT FETCH TRUNCATE TABLE GRANT UPDATE 在发出COMMIT或ROLLBACK语句之前,该事务将一直保持有效。在第一个事务被提 交或回滚之后,下次当连接执行这些语句中的任何语句时,SQL Server都将自动启动一个 新事务。SQL Server将不断地生成一个隐性事务链,直到隐性事务模式关闭为止。 隐性事务模式可以通过使用SET语句来打开或者关闭,或通过数据库API函数和方法进 行设置。 其语法格式为: SET IMPLICIT_TRANSACTIONS { ON | OFF } 当设置为ON时,SET IMPLICIT_TRANSACTIONS将连接设置为隐性事务模式。当设 置为OFF时,则使连接返回到自动提交事务模式。 对于因为该设置为ON而自动打开的事务,用户必须在该事务结束时将其显式提交或回 滚。否则当用户断开连接时,事务及其所包含的所有数据更改将回滚。在事务提交后,执 行上述任一语句即可启动新事务。 隐性事务模式将保持有效,直到连接执行SET IMPLICIT_TRANSACTIONS OFF语句使 连接返回到自动提交模式。在自动提交模式下,如果各个语句成功完成,则提交。 提 示 在进行连接时,SQL Server ODBC驱动程序和用于SQL Server 的Microsoft OLE DB 提供程序自动将IMPLICIT_TRANSACTIONS设置为 OFF。对来自DB-Library应用程序的 连接,SET IMPLICIT_TRANSACTIONS默认为OFF。当SET ANSI_DEFAULTS为ON时, 将启用SET IMPLICIT_TRANSACTIONS。另外,如果连接已经在打开的事务中,则上述 语句不启动新事务。 下面的SQL Server语句演示了在将IMPLICIT_TRANSACTIONS设置为ON时显式或隐 式启动事务。它使用@@TRANCOUNT函数演示打开的事务和关闭的事务: USE test GO SET NOCOUNT ON --不显示受影响的行数 CREATE table t1 (a int) 221 第7章 Chapter 07 SQL高级使用 GO INSERT INTO t1 VALUES (1) GO PRINT '使用显示事务' BEGIN TRAN INSERT INTO t1 VALUES (2) PRINT '事务内的事务数目: '+ CAST(@@TRANCOUNT AS char(5)) COMMIT TRAN PRINT '事务外的事务数目: '+ CAST(@@TRANCOUNT AS char(5)) GO PRINT '设置IMPLICIT_TRANSACTIONS为ON' GO SET IMPLICIT_TRANSACTIONS ON GO PRINT '使用隐式事务' GO --这里不需要BEGIN TRAN语句来定义事务的启动 INSERT INTO t1 VALUES (4) PRINT '事务内的事务数目: '+ CAST(@@TRANCOUNT AS char(5)) COMMIT TRAN PRINT '事务外的事务数目: '+ CAST(@@TRANCOUNT AS char(5)) GO 执行结果为: 使用显示事务 事务内的事务数目: 2 事务外的事务数目: 1 设置IMPLICIT_TRANSACTIONS为ON 使用隐式事务 事务内的事务数目: 1 事务外的事务数目: 0 7.4.5 分布式事务 分布式事务进行的所有数据操作都可以对分布在不同地域的多个服务器同时进行。 SQL Server提供了一个称之为事务管理器的服务器组件,用来对分布式事务进行管理。 实际上跨越两个或多个数据库的单个SQL Server中的事务就是分布式事务。但是,SQL Server对分布式事务进行内部管理,对于用户而言,其操作就像本地事务一样。 对于应用程序,管理分布式事务很像管理本地事务。事务结束时,应用程序请求提交 或回滚事务。不同的是,分布式提交必须由事务管理器管理,以尽量避免出现因网络故障 而导致一个事务由某些资源管理器成功提交,但由另一些资源管理器回滚的情况。通过分 两个阶段管理提交进程可避免这种情况,这称为两阶段提交(2PC)。这两个阶段为: y 准备阶段 当事务管理器收到提交请求时,它给该事务所涉及的所有服务器发送 一个准备命令。然后,每个服务器将尽力使该事务持久,并且所有保存该事务日 志映像的缓冲区将被刷新到磁盘中。当每个服务器完成准备阶段时,它会向事务 新概念 SQL Server 2005 教程 222 管理器返回准备成功或准备失败的消息。 y 提交阶段 如果事务管理器收到所有服务器发来的准备成功消息,它将给每个服 务器发送提交命令。然后服务器就可以完成提交。如果所有服务器都报告提交成 功,那么事务管理器则向应用程序发送一个成功提示。如果有服务器报告准备失 败,那么事务管理器将给每个服务器发送一个回滚命令,并向应用程序表示提交 失败。 在Transact-SQL中启动的分布式事务的结构相对比较简单,其执行过程如下: Transact-SQL脚本或应用程序连接执行启动分布式事务的Transact-SQL语句。 执行该语句的SQL Server成为事务中的主控服务器。 脚本或应用程序对链接的服务器执行分布式查询,或对远程服务器执行远程存储 过程。 当执行了分布式查询或远程过程调用后,主控服务器将自动调用MS DTC以便登 记分布式事务中链接的服务器和远程服务器。 当脚本或应用程序发出COMMIT或ROLLBACK语句时,主控SQL Server将调用 MS DTC管理两阶段提交过程,或者通知链接的服务器和远程服务器回滚其事务。 控制分布式事务的Transact-SQL语句很少,因为多数工作都由SQL Server和MS DTC在 内部完成。Transact-SQL脚本或应用程序中所需的Transact-SQ语句只包括: y 启动分布式事务。使用BEGIN DISTRIBUTED TRANSACTION语句启动显式分布 式事务。 y 对链接的服务器执行分布式查询,或对远程服务器执行远程过程调用。 y 调用标准Transact-SQL语言的COMMIT TRANSACTION、COMMIT WORK、 ROLLBACK TRANSACTION或ROLLBACK WORK语句完成事务。 提 示 对于任意一个Transact-SQL分布式事务,处理Transact-SQL脚本或连接的SQL Server 将自动调用MS DTC以协调事务的提交或回滚。 用OLE DB、ODBC、ADO或DB-Library编写的应用程序使用Transact-SQL分布式事务 的方法可以是:发出Transact-SQL语句启动和停止Transact-SQL分布式事务。但是,OLE DB 和ODBC还包含在API层对管理分布式事务的支持。OLE DB和ODBC应用程序可以使用这 些API函数管理包括其他COM服务器(支持MS DTC事务而非SQL Server)的分布式事务。 它们也可以使用API函数获取对包括多个SQL Server的分布式事务边界的更多控制。 注 意 关于OLE DB和ODBC提供的用于对分布式事务进行管理和设置的API函数的详细信 息,可查阅SQL Server的帮助文档。 223 第7章 Chapter 07 SQL高级使用 7.5 数据的锁定 SQL Server使用锁定确保事务完整性和数据库一致性。锁定可以防止用户读取正在由 其他用户更改的数据,并可以防止多个用户同时更改相同数据。如果不使用锁定,则数据 库中的数据可能在逻辑上不正确,并且对数据的查询可能会产生意想不到的结果。 提 示 虽然SQL Server自动强制锁定,但可以通过了解锁定并在应用程序中自定义锁定来设 计更有效的应用程序。 7.5.1 并发问题 如果没有锁定且多个用户同时访问一个数据库,则当它们的事务同时使用相同的数据 时可能会发生数据不一致问题,这就是并发问题。它包括: y 丢失或覆盖更新(Lost Update); y 未确认的相关性(脏读,Dirty Read); y 不一致的分析(非重复读,Non-Repeatable Read); y 幻象读。 1. 丢失更新 当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新 问题。每个事务都不知道其他事务的存在。最后的更新将重写由其他事务所做的更新,这 将导致数据丢失。 例如,两个用户A和B,分别在T1、T2、T3和T4时间对表中的数据进行操作,如表7.4 所示。 表7.4 丢失更新 用户 T1 T2 T3 T4 A 读取 x=50 x=x-20,并写回数据库 B 读取 x=50 x=x-40,并写回数据库 用户A和B都读取x(x=50),然后分别把x减去20和40,用户A在T3时刻将修改后的x (x=30)写回数据库。随后,用户B在T4时刻将修改后的x(x=10)写回数据库。于是, 对于用户A而言,其修改在T4时刻丢失了。 2. 未确认的相关性(脏读) 当第二个事务选择其他事务正在更新的行时,会发生未确认的相关性问题。第二个事 务正在读取的数据还没有确认并且可能由更新此行的事务所更改。 例如,用户A在T1时刻读取x(x=50),然后将x加上40,用户B在T3时刻由数据缓存 读取x(x=90),但是用户A在T4时刻回滚事务,撤销了对x的修改,数据库中仍然维持x=50, 新概念 SQL Server 2005 教程 224 但是用户B已经把改变的数据(x=90)读走。整个过程如表7.5所示。 表7.5 脏读数据 用户 T1 T2 T3 T4 A 读取 x=50 x=x+40 回滚事务 B 读取缓存 x=90 3. 不一致的分析(非重复读) 当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。 不一致的分析与未确认的相关性类似,因为其他事务也是正在更改第二个事务正在读取的 数据。然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。 不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其他事务更改,所 以该行被非重复读取。 例如,用户A和用户B分别读取x(x=50),在T3时刻用户读取y并计算x+y=80。在T4 时刻用户B把x加上30,并在T5时刻将其写入数据库。在T6时刻用户A读取z,并仍然使用前 面的x和y计算x+y+z=95,如表7.6所示。如果用户A为进行校核而把x、y和z重新读取了一次, 并进行计算,则出现x+y+z=125 表7.6 非重复读 用户 T1 T2 T3 T4 T5 T6 A 读取 x=50 y=30x+y=80 z=15,x+ y+z=95 B 读取 x=50 x=x+30 将 x=80 写入 数据库 4. 幻象读 当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生 幻象读问题。事务第一次读的行范围显示出其中一行已不存在于第二次读或后续读中,因 为该行已被其他事务删除。同样,由于其他事务的插入操作,事务的第二次或后续读显示 有一行已不存在于原始读中。 SQL Server提供了乐观并发控制和悲观并发控制两种: y 乐观并发 乐观并发控制假定不太可能(但不是不可能)在多个用户间发生资源 冲突,允许不锁定任何资源而执行事务。只有试图更改数据时才检查资源以确定 是否发生冲突。如果发生冲突,应用程序必须读取数据并再次尝试进行更改。 y 悲观并发 悲观并发控制根据需要在事务的持续时间内锁定资源。除非出现死锁, 否则事务肯定会成功完成。 乐观并发控制使用游标。SQL Server默认使用悲观并发控制。 225 第7章 Chapter 07 SQL高级使用 7.5.2 事务的隔离级别 尽管可串行性对于事务确保数据库中的数据在所有时间内的正确性相当重要,然而许 多事务并不总是要求完全的隔离。 事务准备接受不一致数据的级别称为隔离级别。隔离级别是一个事务必须与其他事务 进行隔离的程度。较低的隔离级别可以增加并发,但代价是降低数据的正确性。相反,较 高的隔离级别可以确保数据的正确性,但可能对并发产生负面影响。应用程序要求的隔离 级别确定了SQL Server使用的锁定行为。 SQL-92定义了下列4种隔离级别,SQL Server支持所有这些隔离级别: y 未提交读(事务隔离的最低级别,仅可保证不读取物理损坏的数据); y 提交读(SQL Server 2000的默认级别); y 可重复读; y 可串行读(事务隔离的最高级别,事务之间完全隔离)。 下面4种隔离级别允许不同类型的行为,如表7.7所示。 表7.7 4种隔离级别允许的行为 隔离级别 脏读 不可重复读取 幻象 未提交读 是 是 是 提交读 否 是 是 可重复读 否 否 是 可串行读 否 否 否 事务必须运行于可重复读或更高的隔离级别,以防止丢失更新。当两个事务检索相同 的行,然后基于原检索的值对行进行更新时,会发生丢失更新。如果两个事务使用一个 UPDATE语句更新行,并且不基于以前检索的值进行更新,则在默认的提交读隔离级别不 会发生丢失更新。 7.5.3 SQL Server中的锁定 SQL Server具有多粒度锁定,允许一个事务锁定不同类型的资源。为了使锁定的成本 减至最少,SQL Server自动将资源锁定在适合任务的级别。锁定在较小的粒度(例如行) 可以增加并发但需要较大的开销,因为如果锁定了许多行,则需要控制更多的锁。锁定在 较大的粒度(例如表)就并发而言是相当昂贵的,因为锁定整个表限制了其他事务对表中 任意部分进行访问,但要求的开销较低,因为需要维护的锁较少。 SQL Server可以锁定的资源如表7.8所示(表中按粒度增加的顺序列出)。 SQL Server使用不同的锁定模式锁定资源,这些锁定模式确定了并发事务访问资源的 方式,如表7.9所示。 新概念 SQL Server 2005 教程 226 表7.8 SQL Server可以锁定的资源 资源 描述 RID 行标识符。用于单独锁定表中的一行 键(KEY) 索引中的行锁。用于保护可串行事务中的键范围 页(PAG) 8 千字节(KB)的数据页或索引页 扩展盘区(EXT) 相邻的 8 个数据页或索引页构成的一组 表(TAB) 包括所有数据和索引在内的整个表 DB 数据库 表7.9 SQL Server使用的锁定模式 锁模式 描述 共享(S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句 更新(U) 用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更 新时发生常见形式的死锁 排它(X) 用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时对同一 资源进行多重更新 意向 用于建立锁的层次结构。意向锁的类型为:意向共享(IS)、意向排它(IX)以 及与意向排它共享(SIX) 架构 在执行依赖于表架构的操作时使用。架构锁的类型为:架构修改(Sch-M)和架构 稳定性(Sch-S) 大容量更新(BU) 向表中大容量复制数据并指定了 TABLOCK 提示时使用 1. 共享锁 共享(S)锁允许并发事务读取(SELECT)一个资源。资源上存在共享(S)锁时, 任何其他事务都不能修改数据。一旦已经读取数据,便立即释放资源上的共享(S)锁,除 非将事务隔离级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共 享(S)锁。 2. 更新锁 更新(U)锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取 记录,获取资源(页或行)的共享(S)锁,然后修改行,此操作要求锁转换为排它(X) 锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试 将锁转换为排它(X)锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的 排它锁与其他事务的共享模式锁不兼容,发生锁等待。第二个事务试图获取排它(X)锁 以进行更新。由于两个事务都要转换为排它(X)锁,并且每个事务都等待另一个事务释 放共享模式锁,因此发生死锁。 若要避免这种潜在的死锁问题,可以使用更新(U)锁。一次只有一个事务可以获得 资源的更新(U)锁。如果事务修改资源,则更新(U)锁转换为排它(X)锁。否则,锁 227 第7章 Chapter 07 SQL高级使用 转换为共享锁。 3. 排它锁 排它(X)锁可以防止并发事务对资源进行访问。其他事务不能读取或修改排它(X) 锁锁定的数据。 4. 意向锁 意向锁表示SQL Server需要在层次结构中的某些底层资源上获取共享(S)锁或排它(X) 锁。例如,放置在表级的共享意向锁表示事务打算在表中的页或行上放置共享(S)锁。在 表级设置意向锁可防止另一个事务随后在包含那一页的表上获取排它(X)锁。意向锁可 以提高性能,因为SQL Server仅在表级检查意向锁来确定事务是否可以安全地获取该表上 的锁。而无须检查表中的每行或每页上的锁以确定事务是否可以锁定整个表。 意向锁包括意向共享(IS)、意向排它(IX)以及与意向排它共享(SIX),如表7.10所 示。 表7.10 意向锁 锁模式 描述 意向共享(IS) 通过在各资源上放置 S 锁,表明事务的意向是读取层次结构中的部分(而 不是全部)底层资源 意向排它(IX) 通过在各资源上放置 X 锁,表明事务的意向是修改层次结构中的部分(而 不是全部)底层资源。IX 是 IS 的超集 与意向排它共享 (SIX) 通过在各资源上放置 IX 锁,表明事务的意向是读取层次结构中的全部底 层资源并修改部分(而不是全部)底层资源。允许顶层资源上的并发 IS 锁。例如,表的 SIX 锁在表上放置一个 SIX 锁(允许并发 IS 锁),在当 前所修改页上放置 IX 锁(在已修改行上放置 X 锁)。虽然每个资源在一 段时间内只能有一个 SIX 锁,以防止其他事务对资源进行更新,但是其 他事务可以通过获取表级的 IS 锁来读取层次结构中的底层资源 5. 架构锁 执行表的数据定义语言(DDL)操作(例如添加列或除去表)时使用架构修改(Sch-M) 锁。 当编译查询时,使用架构稳定性(Sch-S)锁。架构稳定性(Sch-S)锁不阻塞任何事 务锁,包括排它(X)锁。因此在编译查询时,其他事务(包括在表上有排它(X)锁的事 务)都能继续运行。但不能在表上执行DDL操作。 6. 大容量更新锁 当将数据大容量复制到表,且指定了TABLOCK提示或者使用sp_tableoption设置了table lock on bulk表选项时,将使用大容量更新(BU)锁。大容量更新(BU)锁允许进程将数 据并发地大容量复制到同一表,同时防止其他不进行大容量复制数据的进程访问该表。 新概念 SQL Server 2005 教程 228 7. 锁兼容性 只有兼容的锁类型才可以放置在已锁定的资源上。例如,当控制排它(X)锁时,在 第一个事务结束并释放排它(X)锁之前,其他事务不能在该资源上获取任何类型的(共 享、更新或排它)锁。另一种情况下,如果共享(S)锁已应用到资源,其他事务还可以获 取该项目的共享锁或更新(U)锁,即使第一个事务尚未完成。但是,在释放共享锁之前, 其他事务不能获取排它锁。 资源锁模式有一个兼容性矩阵,显示了与在同一资源上可获取的其他锁相兼容的锁, 如表7.11所示。 表7.11 资源锁模式的兼容性矩阵 请求模式 现有的授权模式 IS S U IX SIX X 意向共享(IS) 是 是 是 是 是 否 共享(S) 是 是 是 否 否 否 更新(U) 是 是 否 否 否 否 意向排它(IX) 是 否 否 是 否 否 与意向排它共享 (SIX) 是 否 否 否 否 否 排它(X) 否 否 否 否 否 否 注 意 意向排它(IX)锁与IX锁模式兼容,因为IX表示打算更新一些行而不是所有行。还 允许其他事务读取或更新部分行,只要这些行不是其他事务当前所更新的行即可。 架构锁和大容量更新锁的兼容性如下: y 架构稳定性(Sch-S)锁与除了架构修改(Sch-M)锁模式之外的所有锁模式相兼 容。 y 架构修改(Sch-M)锁与所有锁模式都不兼容。 y 大容量更新(BU)锁只与架构稳定性(Sch-S)锁及其他大容量更新(BU)锁相 兼容。 7.5.4 自定义锁 虽然SQL Server自动执行锁定,但它仍可以通过以下方法自定义应用程序中的锁定: y 处理死锁和设置死锁优先级。 y 处理超时和设置锁超时持续时间。 y 设置事务隔离级别。 y 对SELECT、INSERT、UPDATE和DELETE语句使用表级锁定提示。 y 配置索引的锁定粒度。 229 第7章 Chapter 07 SQL高级使用 1. 死锁 封锁机制的引入能解决并发用户访问数据的不一致性问题,但是,却会引起死锁。引 起死锁的主要原因是两个进程已经各自锁定一个页,但是又要访问被对方锁定的页。因而 会形成等待圈,形成死锁。 例如,运行事务1的线程T1具有表A上的排它锁。运行事务2的线程T2具有表B上的排它 锁,并且之后需要表A上的锁。事务2无法获得这一锁,因为事务1已拥有它。事务2被阻塞, 等待事务1。然后,事务1需要表B的锁,但无法获得锁,因为事务2将它锁定了,如图7.6 所示。事务在提交或回滚之前不能释放持有的锁。因为事务需要对方控制的锁才能继续操 作,所以它们不能提交或回滚。 图 7.6 死锁 SQL Server能自动发现并解除死锁。当发现死锁时,它会选择其进程累计的CPU时间 最少者对应的用户作为“牺牲者”,以便让其他的进程能继续执行。并发送1205号错误 (@@error=1205)给“牺牲者”。 提 示 SQL Server通常只执行定期死锁检测,而不使用急切模式。因为系统中遇到的死锁数 通常很少,定期死锁检测有助于减少系统中死锁检测的开销。 为了最大程度的避免死锁,可以采取下面的措施: y 按同一顺序访问对象。 y 避免事务中的用户交互。 y 保持事务简短并在一个批处理中。 y 使用低隔离级别。 y 使用绑定连接。 2. 使用绑定连接 当由于另一个事务已拥有一个资源的冲突锁,而导致SQL Server无法将锁授权给该资 源的某个事务时,该事务被阻塞以等待该资源的操作完成。如果这导致了死锁,则SQL Server将终止其中参与的一个事务(不涉及超时)。如果没有出现死锁,则在其他事务释放 事务1 事务2 表A 表B 控制A表 的锁 控制B表 的锁 需要B表 的锁 需要A表 的锁 新概念 SQL Server 2005 教程 230 锁之前,请求锁的事务被阻塞。默认情况下,没有强制的超时期限,并且除了试图访问数 据外(有可能被无限期阻塞),没有其他方法可以测试某个资源是否在锁定之前已被锁定。 LOCK_TIMEOUT语句设置允许应用程序设置语句等待阻塞资源的最长时间。当语句 等待的时间大于LOCK_TIMEOUT设置时,系统将自动取消阻塞的语句,并给应用程序返 回“已超过了锁请求超时时段”的1222号错误信息。 注 意 SQL Server不回滚或取消任何包含该语句的事务。因此,应用程序必须有捕获1222 号错误信息的错误处理程序。如果应用程序没有捕获错误,则会继续运行,并未意识到事 务中的个别语句已取消,从而当事务中的后续语句可能依赖于那条从未执行的语句时,导 致应用程序出错。 若要查看当前LOCK_TIMEOUT的值,可以使用@@LOCK_TIMEOUT全局变量。例如, 下面的SQL语句设置LOCK_TIMEOUT的值为1800ms,并使用@@LOCK_TIMEOUT来显示 该值: SET LOCK_TIMEOUT 1800 GO DECLARE @Timeout int SELECT @Timeout = @@lock_timeout PRINT @Timeout GO 执行结果为: 1800 3. 自定义事务隔离级别 默认情况下,SQL Server 2005在提交读(READ COMMITTED)的一个隔离级别上操 作。但是,应用程序可能必须运行于不同的隔离级别。若要在应用程序中使用更严格或较 宽松的隔离级别,可以通过使用SET TRANSACTION ISOLATION LEVEL语句设置会话的 隔离级别,来自定义整个会话的锁定。 SET TRANSACTION ISOLATION LEVEL语句的语法格式如下: SET TRANSACTION ISOLATION LEVEL { READ COMMITTED | READ UNCOMMITTED | REPEATABLE READ | SERIALIZABLE } 其中4个选项分别代表了4种隔离级别: y READ COMMITTED 提交读。 y READ UNCOMMITTED 未提交读。 y REPEATABLE READ 可重复读。 y SERIALIZABLE 可串行读。 231 第7章 Chapter 07 SQL高级使用 一次只能设置这些选项中的一个,而且设置的选项将一直对那个连接保持有效,直到 显式更改该选项为止。这是默认行为,除非在语句的FROM子句中在表级上指定优化选项。 例如,若要设置事务隔离级别为可串行读,以确保并发事务不能在book表中插入幻象 行,则可执行下述SQL语句: USE bookdb GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE GO BEGIN TRANSACTION SELECT * FROM book GO 执行结果略。 若要确定当前设置的事务隔离级别,可以使用DBCC USEROPTIONS语句,例如: USE bookdb GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE GO DBCC USEROPTIONS GO 执行结果为: Set Option Value ---------------------- --------------------- textsize 2147483647 language 简体中文 dateformat ymd datefirst 7 lock_timeout -1 quoted_identifier SET arithabort SET ansi_null_dflt_on SET ansi_warnings SET ansi_padding SET ansi_nulls SET concat_null_yields_null SET isolation level serializable 4. 锁定提示 可以使用SELECT、INSERT、UPDATE和DELETE语句指定表级锁定提示的范围,以 引导SQL Server 2005使用所需的锁定类型。当需要对对象所获得锁类型进行更精细控制时, 可以使用表级锁定提示。这些锁定提示取代了会话的当前事务隔离级别。 使用的提示关键字和其功能如表7.12所示。 新概念 SQL Server 2005 教程 232 表7.12 提示关键字及其功能 提示关键字 功能 HOLDLOCK 将共享锁保留到事务完成,而不是在相应的表、行或数据页不再需要时就立 即释放锁。HOLDLOCK 等同于 SERIALIZABLE NOLOCK 不要发出共享锁,并且不要提供排它锁。当此选项生效时,可能会读取未提 交的事务或一组在读取中间回滚的页面。有可能发生脏读。仅应用于 SELECT 语句 PAGLOCK 在通常使用单个表锁的地方采用页锁 READCOMMITTED 用于运行在提交读隔离级别的事务相同的锁语义执行扫描。默认情况下,SQL Server 2005 在此隔离级别上操作 READPAST 跳过锁定行。此选项导致事务跳过由其他事务锁定的行(这些行通常会显示 在结果集内),而不是阻塞该事务,使其等待其他事务释放在这些行上的锁。 READPAST 锁提示仅适用于运行在提交读隔离级别的事务,并且只在行级锁 之后读取。仅适用于 SELECT 语句 READUNCOMMITTED 等同于 NOLOCK REPEATABLEREAD 用于运行在可重复读隔离级别的事务相同的锁语义执行扫描 ROWLOCK 使用行级锁,而不使用粒度更粗的页级锁和表级锁 SERIALIZABLE 用于运行在可串行读隔离级别的事务相同的锁语义执行扫描。等同于 HOLDLOCK TABLOCK 使用表锁代替粒度更细的行级锁或页级锁。在语句结束前,SQL Server 一直 持有该锁。但是,如果同时指定 HOLDLOCK,那么在事务结束之前,锁将 被一直持有 TABLOCKX 使用表的排它锁。该锁可以防止其他事务读取或更新表,并在语句或事务结 束前一直持有 UPDLOCK 读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结 束。UPDLOCK 的优点是允许您读取数据(不阻塞其他事务)并在以后更新 数据,同时确保自从上次读取数据后数据没有更改 XLOCK 使用排它锁并一直保持到由语句处理的所有数据上的事务结束时。可以使用 PAGLOCK 或 TABLOCK 指定该锁,这种情况下排它锁适用于适当级别的粒 度 例如,如果将事务隔离级别设置为SERIALIZABLE,并且在SELECT语句中使用表级 锁定提示TABLOCK,则可执行下面的SQL语句: USE bookdb GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE GO BEGIN TRANSACTION SELECT book_name FROM book WITH (TABLOCK) GO 233 第7章 Chapter 07 SQL高级使用 可以使用sp_lock存储过程来查看锁定: EXEC sp_lock GO 执行结果如图7.7所示。 图 7.7 查看锁定 可以使用object_name函数来返回此锁定的数据库对象(表): SELECT object_name(469576711) GO 执行结果为: book 5. 自定义索引的锁定 在大多数情况下,SQL Server 2005动态锁定策略自动选择查询的最佳锁定粒度。在访 问模式很好理解且一致的情况下,限制索引可用的锁定级别是很有益的。 可以使用sp_indexoption系统存储过程来设置用于索引的锁定粒度。若要显示给定索引 的当前锁定选项,可以使用INDEXPROPERTY函数。 7.6 使用游标 关系数据库中的操作会对整个行集产生影响。由SELECT语句返回的行集包括所有满 足该语句WHERE子句中条件的行。由语句所返回的这一完整的行集称为结果集。应用程序, 特别是交互式联机应用程序,并不总能将整个结果集作为一个单元来有效地处理。这些应 用程序需要一种机制,以便每次处理一行或一部分行。游标就是用来提供这种机制的结果 集扩展。 7.6.1 游标的概念 游标包括以下两个部分: y 游标结果集(Cursor Result Set) 由定义该游标的SELECT语句返回的行的集合。 y 游标位置(Cursor Position) 指向这个集合中某一行的指针。 游标的组成及其概念如图7.8所示。 使用该锁定的数 据库对象的ID号 新概念 SQL Server 2005 教程 234 图 7.8 游标 游标使得SQL Server语言可以逐行处理结果集中的数据,游标具有以下优点: y 允许定位在结果集的特定行。 y 从结果集的当前位置检索一行或多行。 y 支持对结果集中当前位置的行进行数据修改。 y 为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性 支持。 y 提供脚本、存储过程和触发器中使用的访问结果集中的数据的Transact-SQL语句。 7.6.2 使用游标 Transact-SQL游标主要用在存储过程、触发器和Transact-SQL脚本中,它们使结果集的 内容对其他Transact-SQL语句同样可用。 使用游标的典型过程如下: 声明Transact-SQL变量包含游标返回的数据。为每一结果集列声明一个变量。声明 足够大的变量,以保存由列返回的值,并声明可从列数据类型以隐性方式转换得到的数据 类型。 使用DECLARE CURSOR语句把Transact-SQL游标与一个SELECT语句相关联。 DECLARE CURSOR语句同时定义游标的特征,比如游标名称以及游标是否为只读或只进 特性。 使用OPEN语句执行SELECT语句并生成游标。 使用FETCH INTO语句提取单个行,并把每列中的数据转移到指定的变量中。然 后,其他Transact-SQL语句可以引用这些变量来访问已提取的数据值。Transact-SQL不支持 提取行块。 结束游标时,使用CLOSE语句。关闭游标可以释放某些资源,比如游标结果集和 对当前行的锁定。但是如果重新发出一个OPEN语句,则该游标结构仍可用于处理。由于游 标仍然存在,此时还不能重新使用游标的名称。DEALLOCATE语句则完全释放分配给游标 的资源,包括游标名称。在游标被释放后,必须使用DECLARE语句来重新生成游标。 其处理过程如图7.9所示。 游标结果集 游标位置 1 刘明耀 北京市海淀区 235 第7章 Chapter 07 SQL高级使用 图 7.9 游标的典型使用过程 1. 声明游标 声明游标使用DECLARE CURSOR语句,其语法格式如下: DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR FOR select_statement [ FOR { READ ONLY | UPDATE [ OF column_name [ , …n ] ] } ] 其中各参数含义如下: y cursor_name 是所定义的Transact-SQL服务器游标名称。cursor_name必须遵从标 识符规则。 y INSENSITIVE 定义一个游标,以创建将由该游标使用的数据的临时副本。对游 标的所有请求都从tempdb中的该临时表中得到应答,因此,在对该游标进行提取 操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。 y SCROLL 指定所有的提取选项(FIRST、LAST、PRIOR、NEXT、RELATIVE、 ABSOLUTE )均可用。如果在SQL-92标准的DECLARE CURSOR 中未指定 SCROLL,则NEXT是唯一支持的提取选项。如果指定SCROLL,则不能也指定 FAST_FORWARD。 y select_statement 是定义游标结果集的标准SELECT 语句。在游标声明的 select_statement 内不允许使用关键字COMPUTE、COMPUTE BY、FOR BROWSE 和INTO。 y READ ONLY 该游标只能读,不能修改。即在UPDATE或DELETE语句的WHERE CURRENT OF子句中不能引用游标。该选项替代要更新的游标的默认功能。 y UPDATE [OF column_name [, … n]] 定义游标内可更新的列。如果指定 OFcolumn_name [,…n]参数,则只允许修改所列出的列。如果在UPDATE中未指定 列的列表,则可以更新所有列。 使用DECLARE语句声明 游标 使用OPEN语句打开游标 空否?直到全部处理完成为止 使用CLOSE语句关闭游标 使用DEALLOCATE语句释放游标 Yes 使用DECLARE CURSOR语句声明游标 使用FETCH INTO语句从游标中提取数据 No 新概念 SQL Server 2005 教程 236 2. 打开游标 打开游标使用OPEN语句,其语法格式如下: OPEN { { [ GLOBAL ] cursor_name } | cursor_variable_name } 其中:GLOBAL 选项指定cursor_name 为全局游标;cursor_name 为游标名称; cursor_variable_name为游标变量名称,该变量引用一个游标。 注 意 只能打开已经声明但还没有打开的游标。 3. 从打开的游标中提取行 游标声明,而且被打开以后,游标位置位于第一行。可以使用FETCH语句从游标结果 集中提取数据。其语法格式如下: FETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar } ] FROM ] { { [ GLOBAL ] cursor_name } | @cursor_variable_name } [ INTO @variable_name [ , …n ] ] 其中各参数的含义为: y NEXT 返回紧跟当前行之后的结果行,并且当前行递增为结果行。如果FETCH NEXT为对游标的第一次提取操作,则返回结果集中的第一行。NEXT为默认的游 标提取选项。 y PRIOR 返回紧临当前行前面的结果行,并且当前行递减为结果行。如果FETCH PRIOR为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。 y FIRST 返回游标中的第一行并将其作为当前行。 y LAST 返回游标中的最后一行并将其作为当前行。 y ABSOLUTE {n | @nvar} 如果n或@nvar为正数,返回从游标头开始的第n行并将 返回的行变成新的当前行。如果n或@nvar为负数,返回游标尾之前的第n行并将返 回的行变成新的当前行。如果n或@nvar为0,则没有行返回。n必须为整型常量且 @nvar必须为 smallint、tinyint或int。 y RELATIVE {n | @nvar} 如果n或@nvar为正数,返回当前行之后的第n行并将返回 的行变成新的当前行。如果n或@nvar为负数,返回当前行之前的第n行并将返回的 行变成新的当前行。如果n或@nvar为0,返回当前行。如果对游标的第一次提取操 作时将FETCH RELATIVE的n或@nvar指定为负数或0,则没有行返回。n必须为整 型常量且@nvar必须为smallint、tinyint或int。 y GLOBAL 指定cursor_name指的是全局游标。 y cursor_name 要从中进行提取的开放游标的名称。如果同时有以cursor_name作为 237 第7章 Chapter 07 SQL高级使用 名称的全局和局部游标存在,若指定为GLOBAL则cursor_name对应于全局游标, 未指定GLOBAL则对应于局部游标。 y @cursor_variable_name 游标变量名,引用要进行提取操作的打开的游标。 y INTO @variable_name[,…n] 允许将提取操作的列数据放到局部变量中。列表中的 各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相 应的结果列的数据类型匹配或是结果列数据类型所支持的隐性转换。变量的数目 必须与游标选择列表中的列的数目一致。 提 示 游标位置决定了结果集中哪一行的数据可以被提取,如果游标方式为FOR UPDATE, 则可决定哪一行数据库可以更新或者删除 @@FETCH_STATUS函数报告上一个FETCH语句的状态,其取值和含义如表7.13所 示。 表7.13 @@FETCH_STATUS函数的取值及其含义 取值 含义 0 FETCH 语句成功 -1 FETCH 语句失败或此行不在结果集中 -2 被提取的行不存在 另外一个用来提供游标活动信息的全局变量为@@ROWCOUNT,它返回受上一语句影 响的行数。 例如: USE bookdb GO SET NOCOUNT ON UPDATE book SET book_name = 'LINUX教程' WHERE book_id = 20 IF @@ROWCOUNT = 0 print '没有行被更新!' GO 执行结果为: 没有行被更新! 4. 关闭游标 关闭游标使用CLOSE语句,其语法格式如下: CLOSE { { [ GLOBAL ] cursor_name } | cursor_variable_name } 其中各参数和上面介绍的相同。 新概念 SQL Server 2005 教程 238 注 意 如果全局游标和局部游标都使用cursor_name作为它们的名称,那么当指定GLOBAL 时cursor_name引用全局游标;否则,cursor_name引用局部游标。 5. 释放游标 释放游标将释放所有分配给此游标的资源。释放游标使用DEALLOCATE语句,其语法 格式为: DEALLOCATE { { [ GLOBAL ] cursor_name } | @cursor_variable_name } 各参数含义同上。 关闭游标并不改变游标的定义,可以再次打开该游标。但是,释放游标就释放了与该 游标有关的一切资源,也包括游标的声明,就不能再次使用该游标了。 6. 游标示例 下面是一个简单的游标使用的例子: /*声明游标*/ DECLARE book_cursor CURSOR FOR SELECT * FROM book /*打开游标*/ OPEN book_cursor /*提取第一行数据*/ FETCH NEXT FROM book_cursor /*关闭和释放游标*/ CLOSE book_cursor DEALLOCATE book_cursor 执行结果为: book_id author_id book_name price publisher 简介 ------- --------- -------------------- -------- ------- --------- 2 2 3D Studio MAX实例精选 35 明耀工作室 NULL 下面使用游标打印一个简单的书籍信息的表格: USE bookdb GO SET NOCOUNT ON /*打印表标题*/ PRINT ' *********书籍信息表***********' PRINT ' ' PRINT '------------------------------------------' PRINT '| 书 名 | 作 者 |价格|' PRINT '------------------------------------------' /*声明变量*/ DECLARE @bookname varchar(100), @authorname varchar(20), @bookprice varchar(40) /*声明游标*/ 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第7章\使用游 标打印报表.avi。 239 第7章 Chapter 07 SQL高级使用 DECLARE book_cursor CURSOR FOR SELECT book_name,author_name,price FROM book,authors WHERE book.author_id=authors.author_id /*打开游标*/ OPEN book_cursor /*提取第一行数据*/ FETCH NEXT FROM book_cursor INTO @bookname, @authorname, @bookprice WHILE @@FETCH_STATUS = 0 BEGIN /*打印数据*/ PRINT '|'+@bookname+'|'+@authorname+'|'+CAST(@bookprice AS char(5))+'|' PRINT '------------------------------------------------------------' /*提取下一行数据*/ FETCH NEXT FROM book_cursor INTO @bookname, @authorname, @bookprice END /*关闭和释放游标*/ CLOSE book_cursor DEALLOCATE book_cursor GO 执行结果如图7.10所示。 图 7.10 生成简单的书籍信息表 7.6.3 游标类型 ODBC和ADO定义了SQL Server 2005所支持的4种游标类型。已经扩展了DECLARE CURSOR语句,这样就可以指定Transact-SQL游标的4种游标类型。这些游标检测结果集变 化的能力和消耗资源(如在tempdb中所占的内存和空间)的情况各不相同。 SQL Server支持的4种API服务器游标类型是: y 静态游标 静态游标的完整结果集在游标打开时建立在tempdb中。静态游标总是 按照游标打开时的原样显示结果集。 y 动态游标 动态游标与静态游标相对。当滚动游标时,动态游标反映结果集中所 新概念 SQL Server 2005 教程 240 做的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会改变。所有 用户做的全部UPDATE、INSERT和DELETE语句均通过游标可见。 y 只进游标 只进游标不支持滚动,它只支持游标从头到尾顺序提取。行只在从数 据库中提取出来后才能检索。 y 键集驱动游标 打开游标时,键集驱动游标中的成员和行顺序是固定的。键集驱 动游标由一套称为键集的唯一标识符(键)控制。键由以唯一方式在结果集中标 识行的列构成。键集是游标打开时来自所有适合SELECT语句的行中的一系列键 值。键集驱动游标的键集在游标打开时建立在tempdb中。 这4种游标类型可在声明游标时,通过STATIC、DYNAMIC、FAST_FORWARD、 KEYSET指定。 提 示 前面介绍的DECLARE CURSOR语句是SQL-92语法,而要指定上面4种游标类型,使 用的则是Transact-SQL对DECLARE CURSOR语句进行扩展后的语法。 7.7 课堂演练 使用游标打印订购书籍的客户名称、订购书名及其金额的报表。SQL语句如下所示: USE bookdb GO SET NOCOUNT ON /*打印表标题*/ PRINT ' *********书籍订购金额汇总表***********' PRINT ' ' PRINT '----------------------------------------' PRINT '| 客户 | 书名 | 总金额 |' PRINT '----------------------------------------' /*声明变量*/ DECLARE @clientname varchar(100), @bookname varchar(100), @totalmoney float /*声明游标*/ DECLARE order_cursor CURSOR FOR SELECT clients.client_name,book.book_name, SUM(orderform.book_number*book.price) AS total FROM clients,orderform,book WHERE clients.client_id=orderform.client_id AND book.book_id= orderform.book_id GROUP BY clients.client_name,book.book_name WITH CUBE /*打开游标*/ OPEN order_cursor /*提取第一行数据*/ FETCH NEXT FROM order_cursor INTO @clientname, @bookname, @totalmoney 241 第7章 Chapter 07 SQL高级使用 WHILE @@FETCH_STATUS = 0 BEGIN /*打印数据*/ PRINT '|'+@ clientname +'|'+@ bookname+'|'+CAST(@totalmoney AS char(5))+'|' PRINT '-------------------------------------' /*提取下一行数据*/ FETCH NEXT FROM book_cursor INTO @ clientname, @ bookname, @ totalmoney END /*关闭和释放游标*/ CLOSE order_cursor DEALLOCATE order_cursor GO 7.8 小结 本章介绍了SQL语言的高级使用及其技巧,包括SQL高级查询、错误处理、ntext、text 和image数据的管理、事务的概念和使用、数据的锁定以及游标的使用。 高级查询包括数据汇总、联接查询、子查询等。它们都是包含在SELECT语句中的子 句,都是对SELECT功能的扩展。 除了使用全局变量@@ERROR来处理错误外,还可以使用RAISERROR函数,它在把 消息返回给应用程序方面的功能更强大。并可代替PRINT的部分功能。 ntext、text和image数据类型在单个值中可以包含非常大的数据量(最大可达2GB)。 因此,在检索这些值时,需要一些特殊的步骤。通常需要结合SQL Server提供的一些函数 来完成。 事务是SQL Server中的单个逻辑单元,数据的锁定是为了解决数据的并发性问题而提 出的,可以使用事务和锁定数据来保证数据的一致性和完整性。 游标提供了对结果集中的单行数据进行操作的手段。可以使用游标对数据进行更新和 删除。对于SQL-92标准,它只提供了只读和可以修改两种方式。在Transact-SQL中,对游 标类型进行了扩展,可以包括4种游标,它们检测结果集变化的能力和消耗资源的情况各不 相同。可根据自己需要选择相应的游标类型。 7.9 课后练习 7.9.1 简答题 (1)简述事务的概念和SQL Server中的实现方式。 (2)简单叙述数据的并发性问题。 新概念 SQL Server 2005 教程 242 7.9.2 操作题 (1)根据orderform表中的订单记录来检索客户名称及其订购书籍的总金额。 操作步骤提示: 可以使用下面的SQL语句: USE bookdb GO SELECT clients.client_name,SUM(orderform.book_number*book.price) AS 总 金额 FROM clients,orderform,book WHERE clients.client_id=orderform.client_id AND orderform.book_id = book.book_id GROUP BY clients.client_name (2)检索哪本书没有被订购。 操作步骤提示: 可以使用下面的SQL语句: USE bookdb GO SELECT * FROM book WHERE book_id NOT IN( SELECT book_id FROM orderform) (3)将上述两个查询结果同时显示。 操作步骤提示: 使用UNION组合两个结果。 第 8 章 视 图 08 Chapter 本章导读: ” 视图的基本概念 ” 创建视图 ” 视图的修改 ” 视图的删除 ” 通过视图修改数据 8.1 概述 视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称 的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自 由定义视图的查询所引用的表,并且在引用视图时动态生成。 视图是从一个或者多个表中使用SELECT语句导出的。那些用来导出视图的表称为基 表。视图也可以从一个或者多个其他视图中产生。导出视图的SELECT语句存放在数据库 中,而与视图定义相关的数据并没有在数据库中另外保存一份,因此,视图也称为虚表。 视图的行为和表类似,可以通过视图查询表的数据,也可以修改表的数据,如图8.1所示。 图 8.1 视图 titles表 Publisher表 视图 新概念 SQL Server 2005 教程 244 对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前 或其他数据库的一个或多个表,或者其他视图。所以说,视图是一种SQL查询。在数据库 中,存储的是视图的定义,而不是视图查询的数据。通过这个定义,对视图查询最终转换 为对基表的查询。 提 示 SQL Server处理视图的过程为:首先在数据库中找到视图的定义,然后将其对视图的 查询转换为对基表的查询的等价查询语句,并且执行这个等价的查询。通过这种方法,SQL Server可以保持表的完整性。 视图通常用来集中、简化和自定义每个用户对数据库的不同认识。视图可用作安全机 制,方法是允许用户通过视图访问数据,而不授予用户直接访问视图基础表的权限。从(或 向)SQL Server 2005复制数据时也可使用视图来提高性能并分区数据。 视图具有下述优点和作用: y 将数据集中显示 视图让用户能够着重于他们所感兴趣的特定数据和所负责的特 定任务。不必要的数据可以不出现在视图中。这同时增强了数据的安全性,因为 用户只能看到视图中所定义的数据,而不是基础表中的数据。 y 简化数据操作 视图可以简化用户操作数据的方式。可将经常使用的联接、投影、 联合查询和选择查询定义为视图,这样,用户每次对特定的数据执行进一步操作 时,不必指定所有条件和限定。另外,在数据库设计时,所使用的名称不能直观 显示出字段的含义,而在视图中,可以将其定义为非常容易理解的名称,从而为 用户使用数据库提供了很大的方便。 y 自定义数据 视图允许用户以不同的方式查看数据,即使他们同时使用相同的数 据时也如此。这在具有不同目的和技术水平的用户共享同一个数据库时尤其有利。 y 使用视图可以重新组织数据以便导入导出数据 可使用视图将数据导出至其他应 用程序。例如,可以使用视图来重新组织不同表之间的数据,然后将其导出到Excel 中统计成图表。 y 组合分区数据 Transact-SQL语言中的UNION集合运算符可在视图内使用,以将 来自不同表的两个或多个查询结果组合成单一的结果集。这在用户看来是一个单 独的表,称为分区视图。通过使用分区视图,数据的外观像是一个单一表,且能 以单一表的方式进行查询,而无须手动引用真正的基础表。 8.2 创建视图 要使用视图,首先必须创建视图。视图在数据库中是作为一个独立的对象进行存储的。 创建视图要考虑如下的原则: y 只能在当前数据库中创建视图。但是,如果使用分布式查询定义视图,则新视图 所引用的表和视图可以存在于其他数据库中,甚至其他服务器上。 245 第8章 Chapter 08 视 图 y 视图名称必须遵循标识符的规则,且对每个用户必须为唯一。此外,该名称不得 与该用户拥有的任何表的名称相同。 y 可以在其他视图和引用视图的过程之上建立视图。SQL Server 2005允许嵌套多达 32级视图。 y 定义视图的查询不可以包含ORDER BY、COMPUTE或COMPUTE BY子句或INTO 关键字。 y 不能在视图上定义全文索引定义。 y 不能创建临时视图,也不能在临时表上创建视图。 y 不能对视图执行全文查询,但是如果查询所引用的表被配置为支持全文索引,就 可以在视图定义中包含全文查询。 一般情况下,不必为在创建视图时指定列名,SQL Server使视图中的列与定义视图的 查询所引用的列具有相同的名称和数据类型。但是有些情况必须指定列名,这些情况包括: y 视图中包含任何从算术表达式、内置函数或常量派生出的列。 y 视图中两列或多列具有相同名称(通常由于视图定义包含联接,而来自两个或多 个不同表的列具有相同的名称)。 y 希望使视图中的列名与它的源列名不同(也可以在视图中重命名列)。无论重命 名与否,视图列都会继承其源列的数据类型。 提 示 若要创建视图,数据库所有者必须具有创建视图的权限,并且对视图定义中所引用 的表或视图要有适当的权限。 查询和视图虽然很相似,但还是有很多的区别。主要区别如下: y 存储方式 视图存储为数据库设计的一部分,而查询则不是。 y 更新结果 对视图和查询的结果集更新限制是不同的。 y 排序结果 可以排序任何查询结果,但是只有当视图包括TOP子句时才能排序视 图。 y 参数设置 可以为查询创建参数,但不能为视图创建参数。 y 加密 可以加密视图,但不能加密查询。 8.2.1 使用SQL Server Management Studio管理平台创建视图 视图保存在数据库中而查询不是,因此创建新视图的过程与创建查询的过程不同。通 过企业管理器不但可以创建数据库和表,也可以创建视图。 在SQL Server Management Studio中,创建视图的操作步骤如下: 打开SQL Server Management Studio窗口,打开要创建视图的 数据库文件夹,右击“视图”文件夹,然后执行“新建视图”命令, 打开“添加表”对话框,如图8.2所示。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第8章\创建视 图.avi。 新概念 SQL Server 2005 教程 246 图 8.2 “添加表”对话框 提 示 在选择时,可以使用Ctrl键或者Shift键来选择多个表、视图或者函数。 选择完成后,单击“关闭”按钮。 选择表、视图或者函数后,单击“关闭”按钮。此时,在SQL Server Management Studio界面的第一栏中,可看到添加进来的book和authors表,并且显示出了它们之间的关联。 在每一字段前面都包含一个复选框,可以选择该复选框将其添加到视图中。依次 选择book_name、author_name、price和publisher字段,如图8.3所示。这里也可以直接在第 三栏中输入SELECT语句。 图 8.3 新建视图 选择book和authors两 个表,然后单击“添加”按 钮。 显示视图所使用 的表及其关联 创建该视图 的SQL语句 247 第8章 Chapter 08 视 图 提 示 在选择视图需要使用的字段时,可以按照自己想要的顺序来选择,这样的选择顺序 就是在视图中的顺序。另外,在选择的过程中,第三栏中的SELECT语句也随着变化 在“别名”列上,依次输入选择字段的别名,如图8.4所示。 图 8.4 输入别名 单击工具栏上的“保存”按钮,然后在弹出的 对话框中输入视图的名称,这里输入book_info,如图8.5 所示。 单击“确定”按钮,即可完成视图book_info的 创建。 8.2.2 使用SQL语句创建视图 使用CREATE VIEW语句创建视图的完整语法为: CREATE VIEW [ < database_name > .] [ < owner > .] view_name [ ( column [ , … n ] ) ] [ WITH < view_attribute > [ , …n ] ] AS select_statement [ WITH CHECK OPTION ] < view_attribute > ::= { ENCRYPTION | SCHEMABINDING | VIEW_METADATA } 各参数的含义如下: y view_name 视图的完整名称,它必须符合标识符规则,并可通过[ < database_name > .]和[ < owner > .]指定数据库名和所有者名称。 y n 是表示可以指定多列的占位符。 y AS 是视图要执行的操作。 y select_statement 是定义视图的SELECT语句。该语句可以使用多个表或其他视图。 若要从创建视图的SELECT子句所引用的对象中选择,必须具有适当的权限。 y WITH CHECK OPTION 强制视图上执行的所有数据修改语句都必须符合由 select_statement设置的准则。通过视图修改行时,WITH CHECK OPTION可确保提 交修改后仍可通过视图看到修改的数据。 字段别名 图 8.5 输入视图名称 新概念 SQL Server 2005 教程 248 y WITH ENCRYPTION 表示 SQL Server加密包含CREATE VIEW语句文本的系统 表列。使用WITH ENCRYPTION可防止将视图作为SQL Server复制的一部分发布。 y SCHEMABINDING 将视图绑定到架构上。指定SCHEMABINDING时,SELECT 语句select_statement必须包含所引用的表、视图或用户定义函数的两部分名称 (owner.object)。 y VIEW_METADATA 指定为引用视图的查询请求浏览模式的元数据时,SQL Server将向DBLIB、ODBC和OLE DB API返回有关视图的元数据信息,而不是返回 基表或表。 例如,下面的SQL语句创建book_total视图,其中包括了书名、价格、定购的数量和总 额: USE bookdb GO CREATE VIEW dbo.book_total AS SELECT dbo.book.book_name AS 书名, dbo.book.price AS 价格, dbo.orderform.book_number AS 数量, dbo.book.price*dbo.orderform.book_number AS 总额 FROM dbo.orderform INNER JOIN dbo.book ON dbo.orderform.book_id = dbo.book.book_id GO 在上面创建的视图中,“总额”列是由“价格”和“数量”两个列相乘得到的,因此 必须指定列名。而其余的列则可以使用别名,也可以不使用别名。 视图中可以使用的列最多可达1024列。创建视图时,与视图有关的信息将存储在下列 目录视图中:sys.views、sys.columns和sys.sql_dependencies。CREATE VIEW语句的文本将 存储在sys.sql_modules目录视图中。 8.3 使用视图 通过视图可以检索基表中的书籍,也可以通过视图来修改基表中的数据,例如插入、 删除和修改记录。 8.3.1 使用视图进行数据检索 视图是基于基表生成的,因此可以用来将需要的数据集中在一起,而不需要的数据则 不需要显示。 使用视图来检索数据,可以像对表一样来对视图进行操作。例如,使用上面创建的 book_total视图来查询所有定购书籍的书名及其总金额: SELECT 书名,总额 FROM book_total 执行结果如下: 249 第8章 Chapter 08 视 图 书名 总额 ------------------------------------------ ------------- 3D Studio MAX实例精选 1750 Office 2007 中文版使用指南 280 AutoCAD 2008 中文版使用指南 250 Windows 2003 Server网络管理 1125 Linux 使用指南 480 Mathematica 5.0入门与提高 900 和表类似,也可以通过SQL Server Management Studio管理平台来查看视图的数据,操 作步骤如下: 打开SQL Server Management Studio,打开bookdb数据库,打开“视图”文件夹。 在要查看的视图上右击鼠标,在打开的快捷菜单中,执行“打开视图”命令,即 可打开bookt_total视图可以检索到的数据,如图8.6所示。 图 8.6 通过视图检索数据 8.3.2 通过视图修改数据 通过视图修改其中的某些行时,SQL Server将把它转换为对基表的某些行的操作。对 于简单的视图来说,可能比较容易实现,但是对于比较复杂的视图,可能就不能通过视图 进行修改。 通过视图修改基表中的数据应注意下面的问题: y 如果在视图定义中使用了WITH CHECK OPTION子句,则所有在视图上执行的数 据修改语句都必须符合定义视图的SELECT语句中所设定的条件。如果使用了 WITH CHECK OPTION子句,修改行时须注意不让它们在修改完成后从视图中消 失。任何可能导致行消失的修改都会被取消,并显示错误信息。 y SQL Server必须能够明确地解析对视图所引用基表中的特定行所做的修改操作。不 能在一个语句中对多个基础表使用数据修改语句。因此,列在UPDATE或INSERT 语句中的列必须属于视图定义中的同一个基表。 y 对于基础表中需更新而又不允许空值的所有列,它们的值在INSERT语句或 DEFAULT定义中指定。这将确保基础表中所有需要值的列都可以获取值。 y 如果在视图中删除数据,在视图定义的FROM子句中只能列出一个表。 通过视图修改数据也是通过INSERT、UPDATE和DELETE语句来完成的。 例如,下面的SQL语句在test数据库中创建一个表和基于该表的视图,并利用视图插入 了一笔记录: 新概念 SQL Server 2005 教程 250 USE test GO /*如果表Table1存在,则删除*/ IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Table1') DROP TABLE Table1 GO /*如果视图View1存在,则删除*/ IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'View1') DROP VIEW View1 GO /*创建表Table1*/ CREATE TABLE Table1 ( column_1 int, column_2 varchar(30)) GO /*创建视图View1*/ CREATE VIEW View1 AS SELECT column_2, column_1 FROM Table1 GO /*通过视图View1插入一笔记录*/ INSERT INTO View1 VALUES ('Row 1',1) /*查看插入的记录*/ SELECT * FROM Table1 GO 执行结果如下: column_1 column_2 ------------- ----------------- 1 Row 1 8.4 视图的修改 如果基表发生变化,或者要通过视图查询更多的信息,都需要修改视图的定义。可以 删除视图,然后重新创建一个新的视图,但是也可以在不除去和重新创建视图的条件下更 改视图名称或修改其定义。 8.4.1 修改视图 修改视图的定义可以通过SQL Server Management Studio管理平台来进行,也可以使用 ALTER VIEW语句来完成。 1. 使用 SQL Server Management Studio 修改视图 使用SQL Server Management Studio管理平台修改视图的操作步骤如下: 打开SQL Server Management Studio,打开“数据库”文件夹,打开该视图所属的 数据库,然后单击“视图”。 在右侧的详细信息窗口中,右击要修改的视图,然后选择“设计视图”命令。即 251 第8章 Chapter 08 视 图 可打开设计视图对话框。在此对话框中,可修改视图的定义。 如果要添加表,则可以在上面的窗口中右击鼠标,然后选择“添加表”命令。若 要删除表,则可以在表的标题栏上右击鼠标,然后选择“删除”命令。 设置完成后,单击“关闭”按钮。要保存对视图的修改,可单击工具栏上的“保 存”按钮。 2. 使用 ALTER VIEW 语句 使用ALTER VIEW语句可以更改一个先前创建的视图(用CREATE VIEW创建),包括 索引视图,但不影响相关的存储过程或触发器,也不更改权限。 ALTER VIEW语句的语法格式如下: ALTER VIEW [ < database_name > .] [ < owner > .] view_name [ ( column [ , … n ] ) ] [ WITH < view_attribute > [ , …n ] ] AS select_statement [ WITH CHECK OPTION ] < view_attribute > ::= { ENCRYPTION | SCHEMABINDING | VIEW_METADATA } 其中view_name为要修改的视图的名称,其余各参数与8.2.3小节中的CREATE VIEW语 句中的参数相同。 8.4.2 重命名视图 在重命名视图时,应注意以下问题: y 要重命名的视图必须位于当前数据库中。 y 新名称必须遵守标识符规则。 y 只能重命名自己拥有的视图。 y 数据库所有者可以更改任何用户视图的名称。 重命名视图可以通过SQL Server Management Studio来完成,也可以通过sp_rename存储 过程来完成。 在SQL Server Management Studio中,可以像在资源管理器中更改文件夹或者文件名一 样,在要重命名的视图上右击鼠标,执行“重命名”命令,然后输入新的视图名称即可。 sp_rename存储过程可以用来重命名视图,其语法格式如下: sp_rename [ @objname = ] 'object_name' , [ @newname = ] 'new_name' [ , [ @objtype = ] 'object_type' ] 其中各参数含义如下: y [ @objname = ] 'object_name' 视图的当前名称。 y [ @newname = ] 'new_name' 视图的新名称。 y [@objtype =] 'object_type' 要重命名的对象的类型。object_type为varchar(13)类型, 新概念 SQL Server 2005 教程 252 其默认值为NULL。其取值及其含义如表8.1所示。 表8.1 object_type的取值及其含义 取值 说明 COLUMN 要重命名的列 DATABASE 用户定义的数据库。要重命名数据库时需用此选项 INDEX 用户定义的索引 OBJECT 在 sysobjects 中跟踪的类型的项目。例如,OBJECT 可用来重命名约束(CHECK、 FOREIGN KEY、PRIMARY/UNIQUE KEY)、用户表、视图、存储过程、触发 器和规则等对象 USERDATATYPE 通过执行 sp_addtype 而添加的用户定义数据类型 提 示 sp_rename存储过程不仅可以更改视图的名称,而且可以更改当前数据库中用户创建 对象(如表、列或用户定义数据类型)的名称。 例如,下面的SQL语句将视图book_info重命名为“书籍信息”: USE bookdb GO EXEC sp_rename 'book_info','书籍信息' GO 执行结果为: 更改对象名的任一部分都可能破坏脚本和存储过程。 执行下面的语句也可以完成相同的功能: USE bookdb GO EXEC sp_rename 'book_info','书籍信息', 'OBJECT' GO 8.5 视图信息的查询 如果视图定义没有加密,即可获取该视图定义的有关信息。在实际工作中,可能需要 查看视图定义,以了解数据从源表中的提取方式。 8.5.1 使用SQL Server Management Studio 使用SQL Server Management Studio查看视图信息的操作步骤如 下: 打开SQL Server Management Studio窗口,然后打开“数据库” 文件夹,打开该视图所属的数据库,选择“视图”文件夹。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第8章\查看视 图.avi。 253 第8章 Chapter 08 视 图 在右侧详细信息窗口中,右击要查看信息的视图,例如“book_info”视图,然后 执行“属性”命令,打开“视图属性”对话框。 在“常规”选项卡中,可以查看视图的名称以及其他一些选项设置。 在“选择页”列表中,选择“权限”选项,打开“权限”选项卡,如图8.7所示。 在此选项卡中,可以设置用户对该视图所具有的权限。 图 8.7 视图的权限设置 设置完成后,单击“确定”按钮,关闭视图属性窗口。 8.5.2 使用sp_helptext存储过程 使用sp_helptext存储过程可以显示规则、默认值、未加密的存储过程、用户定义函数、 触发器或视图的文本等信息。 sp_helptext存储过程的语法格式如下: sp_helptext [ @objname = ] 'name' 其中[@objname =] 'name'为对象的名称,将显示该对象的定义信息。对象必须在当前数 据库中。name的数据类型为nvarchar(776),没有默认值。 例如,可以使用下面的SQL语句来查看视图“书籍信息”的定义: EXEC sp_helptext '书籍信息' 执行结果如图8.8所示。 图 8.8 查询视图定义 新概念 SQL Server 2005 教程 254 sp_helptext在多个行中显示用来创建对象的文本,其中每行有Transact-SQL定义的255 个字符。这些定义只驻留在当前数据库的syscomments表的文本中。 8.6 视图的删除 在创建视图后,如果不再需要该视图或想清除视图定义以及与之相关联的权限,可以 删除该视图。删除视图后,表和视图所基于的数据并不受影响。任何使用基于已删除视图 的对象的查询将会失败,除非创建了同样名称的一个视图。 删除视图时,定义在系统表sysobjects、syscolumns、syscomments、sysdepends和 sysprotects中的视图信息也会被删除,而且视图的所有权限也一并被删除。 8.6.1 使用SQL Server Management Studio 使用SQL Server Management Studio删除视图的操作和删除表的操作类似,其操作步骤 如下: 打开SQL Server Management Studio窗口,打开“数据库”文件夹,打开该视图所 属的数据库,然后选择“视图”文件夹。 在对象资源管理器详细信息窗口中,右击视图,然后选择“删除”命令,打开“删 除对象”对话框。 单击“确定”按钮即可删除视图;单击“取消”按钮取消删除操作。 8.6.2 使用Transact-SQL 使用DROP VIEW语句可从当前数据库中删除一个或多个视图。其语法格式为: DROP VIEW { view } [ , …n ] 其中view是要删除的视图名称,n是表示可以指定多个视图的占位符。 例如,下面的语句检查test数据库中是否有View1视图,若有,则删除: USE test GO /*如果视图View1存在,则删除*/ IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'View1') DROP VIEW View1 GO 提 示 已除去的表(使用DROP TABLE语句除去)上的任何视图必须通过使用DROP VIEW 显式除去。默认情况下,将DROP VIEW权限授予视图所有者,该权限不可转让。然而, db_owner和db_ddladmin固定数据库角色成员和sysadmin固定服务器角色成员可以通过在 DROP VIEW内显式指定所有者除去任何对象。 255 第8章 Chapter 08 视 图 8.7 课堂演练 创建一个视图,名为“订单”,并使用它来检索订购日期、客户名称、书名、单价、 数量和总额。 参考SQL语句如下: CREATE VIEW dbo.订单 AS SELECT dbo.orderform.order_date AS 订购日期, dbo.book.book_name AS 书名, dbo.book.price AS 单价, dbo.orderform.book_number AS 数量, dbo.clients.client_name AS 客户名, dbo.orderform.book_number * dbo.book.price AS 总额 FROM dbo.book INNER JOIN dbo.orderform ON dbo.book.book_id = dbo.orderform.book_id INNER JOIN dbo.clients ON dbo.orderform.client_id = dbo.clients.client_id 8.8 小结 视图是基于基表而产生的一种虚拟表,本身并不存储任何数据,当从视图中检索数据 时,SQL Server将其转换为对基表的SELECT语句,从而获得需要的数据。使用视图可以很 方便地组织需要的数据、简化数据查询,并且可以提高安全性。 视图在数据库中是作为一个独立的对象存在的,视图名称必须遵循标识符的规则,而 且对每个用户必须为唯一。只能在当前数据库中创建视图。 创建、删除和修改视图均可以通过企业管理器和使用Transact-SQL语言两种方式来完 成,企业管理器为图形化界面,可以通过对话框来完成。而Transact-SQL语言灵活性更大, 并且可以用在程序设计中。 不仅可以通过视图检索数据,也可以通过视图来修改数据,但是要受到很多方面的限 制,例如不能同时对多个表插入和更新数据等。 8.9 课后练习 8.9.1 选择题和简答题 (1)下面关于视图的说明,哪一个正确? A. 视图是将基表中的数据检索出来后重新组成的一个新表 B. 视图是一种虚拟表,本身保存的只是视图的定义,查看视图数据时,SQL Server将 其定义转换为相应的SELECT语句,然后进行检索并显示结果 C. 通过视图可以修改多个基表的数据 D. 对任何视图,都可以通过该视图修改基表的数据 (2)简述CREATE VIEW语句中的WITH CHECK OPTION选项的含义。 新概念 SQL Server 2005 教程 256 (3)如何通过视图插入、更新和删除数据? (4)使用视图修改数据时,需要注意哪几点? 8.9.2 操作题 创建视图“客户订购金额汇总”视图,包括客户名称和订购书籍的总数目。 操作步骤提示,创建视图的SQL语句为: USE bookdb CREATE VIEW AS SELECT clients.client_name,SUM(orderform.book_number) AS 书籍总数 FROM clients,orderform WHERE clients.client_id=orderform.client_id GROUP BY clients.client_name 第 9 章 数据库完整性 09 Chapter 本章导读: ” 约束 ” 默认和规则 ” 存储过程的创建 ” 存储过程的执行 ” 存储过程的修改和删除 ” 存储过程的参数 ” 触发器的创建和使用 ” 触发器的修改和删除 9.1 概述 数据库完整性就是确保数据库中的数据的一致性和正确性。在第1章中,介绍了4类数 据完整性。SQL Server提供了相应的组件以实现数据库的完整性,如表9.1所示。 表9.1 SQL Server提供的数据完整性组件 完整性类型 SQL Server 提供的数据完整性组件 实体完整性 索引、UNIQUE 约束、PRIMARY KEY 约束和 IDENTITY 属性 域完整性 FOREIGN KEY 约束、CHECK 约束、DEFAULT 定义、NOT NULL 定义和规则 参照完整性 FOREIGN KEY、CHECK 约束和触发器 用户定义完整性 CREATE TABLE 中的所有列级和表级约束、存储过程和触发器 下面对这些组件进行详细介绍。 9.2 约束 设计表时需要识别列的有效值并决定如何强制实现列中数据的完整性。SQL Server 2005提供多种强制数据完整性的机制: y PRIMARY KEY约束; y FOREIGN KEY约束; y UNIQUE约束; 新概念 SQL Server 2005 教程 258 y CHECK约束; y NOT NULL(为空性)。 上述约束是SQL Server 2005自动强制数据完整性的方式,它们定义关于列中允许值的 规则,是强制完整性的标准机制。使用约束优先于使用触发器、规则和默认值。查询优化 器也使用约束定义生成高性能的查询执行计划。 其中NOT NULL前面已经使用过,下面介绍其他4种约束。 9.2.1 PRIMARY KEY约束 PRIMARY KEY约束标识列或列集,这些列或列集的值唯一标识表中的行。PRIMARY KEY约束可以在下面情况下使用: y 作为表定义的一部分在创建表时创建。 y 添加到尚没有PRIMARY KEY约束的表中(一个表只能有一个PRIMARY KEY约 束)。 y 如果已有PRIMARY KEY约束,则可对其进行修改或删除。例如,可以使表的 PRIMARY KEY约束引用其他列,更改列的顺序、索引名、聚集选项或PRIMARY KEY约束的填充因子。定义了PRIMARY KEY约束的列的列宽不能更改。 在一个表中,不能有两行包含相同的主键值。不能在主键内的任何列中输入NULL值。 在数据库中NULL是特殊值,代表不同于空白和0值的未知值。建议使用一个小的整数列作 为主键。每个表都应有一个主键。 例如,下面的SQL语句创建一个名为student的表,其中指定student_number为主键: USE test GO CREATE TABLE student (sutdent_number int PRIMARY KEY, student_name char(30)) GO 注 意 若要使用Transact-SQL修改PRIMARY KEY,必须先删除现有的PRIMARY KEY约 束,然后再用新定义重新创建。 如果在创建表时指定一个主键,则SQL Server会自动创建一个名为“PK_”且后跟表名 的主键索引。这个唯一索引只能在删除与它保持联系的表或者主键约束时才能删除掉。如 果不指定索引类型,缺省时创建一个聚集索引。 9.2.2 FOREIGN KEY约束 FOREIGN KEY约束标识表之间的关系。用于强制参照完整性,为表中一列或者多列 数据提供参照完整性。FOREIGN KEY约束也可以参照自身表中的其他列,这种参照称为自 参照。 FOREIGN KEY约束可以在下面情况下使用: 259 第9章 Chapter 09 数据库完整性 y 作为表定义的一部分在创建表时创建。 y 如果FOREIGN KEY约束与另一个表(或同一表)已有的PRIMARY KEY约束或 UNIQUE约束相关联,则可向现有表添加FOREIGN KEY约束。一个表可以有多个 FOREIGN KEY约束。 y 对已有的FOREIGN KEY约束进行修改或删除。例如,要使一个表的FOREIGN KEY 约束引用其他列。定义了FOREIGN KEY约束列的列宽不能更改。 下面就是一个使用FOREIGN KEY约束的例子: CREATE TABLE product (product_number int, student_number int FOREIGN KEY REFERENCES student(student_number) ON DELETE NO ACTION) GO 如果一个外键值没有主键,则不能插入带该值(NULL 除外)的行。如果尝试删除现 有外键指向的行,ON DELETE子句将控制所采取的操作。ON DELETE子句有两个选项: y NO ACTION 指定删除因错误而失败。 y CASCADE 指定还将删除包含指向已删除行的外键的所有行。 如果尝试更新现有外键指向的候选键值,ON UPDATE子句将定义所采取的操作。它 也支持NO ACTION和CASCADE选项。 使用FOREIGN KEY约束,还应注意以下几个问题: y 一个表中最多可以有253个可以参照的表,因此每个表最多可以有253个FOREIGN KEY约束。 y FOREIGN KEY约束中,只能参照同一个数据库中的表,而不能参照其他数据库中 的表。 y FOREIGN KEY子句中的列数目和每个列指定的数据类型必须和REFERENCE子句 中的列相同。 y FOREIGN KEY约束不能自动创建索引。 y 参照同一个表中的列时,必须只使用REFERENCE子句,而不能使用FOREIGN KEY 子句。 y 在临时表中,不能使用FOREIGN KEY约束。 9.2.3 UNIQUE约束 UNIQUE约束在列集内强制执行值的唯一性。对于UNIQUE约束中的列,表中不允许 有两行包含相同的非空值。主键也强制执行唯一性,但主键不允许空值,而且每个表中主 键只能有一个,但是UNIQUE列却可以有多个。UNIQUE约束优先于唯一索引。 在向表中的现有列添加UNIQUE约束时,默认情况下SQL Server 2005检查列中的现有 数据,确保除NULL外的所有值均唯一。如果对有重复值的列添加UNIQUE约束,SQL Server 将返回错误信息并不添加约束。 新概念 SQL Server 2005 教程 260 SQL Server自动创建UNIQUE索引来强制UNIQUE约束的唯一性要求。因此,如果试图 插入重复行,SQL Server将返回错误信息,说明该操作违反了UNIQUE约束并不将该行添加 到表中。除非明确指定了聚集索引,否则,默认情况下创建唯一的非聚集索引以强制 UNIQUE约束。 例如,下面的SQL语句创建了一个test2表,其中指定了c1字段不能包含重复的值: USE test GO CREATE TABLE test2 (c1 int UNIQUE, c2 int) GO INSERT test2 VALUES(1,100) GO 如果再插入一行: INSERT test2 VALUES(1,200) 则会出现如下的错误: 消息2627,级别14,状态1,第1 行 违反了UNIQUE KEY 约束'UQ__test2__0519C6AF'。不能在对象'dbo.test2' 中插入重复键。 语句已终止。 注 意 删除UNIQUE约束,以删除对约束中所包含列或列组合输入值的唯一性要求。如果 相关列是表的全文键,则不能删除UNIQUE约束。 9.2.4 CHECK约束 CHECK约束通过限制用户输入的值来加强域完整性。它指定应用于列中输入的所有值 的布尔(取值为TRUE或FALSE)搜索条件,拒绝所有不取值为TRUE的值。可以为每列指 定多个CHECK约束。 例如,下面的SQL语句创建一个成绩(score)表,其中使用CHECK约束来限定成绩只 能为0~100分: CREATE TABLE score (sutdent_number int, score int NOT NULL CHECK(score>=0 AND score <=100) ) 9.2.5 列约束和表约束 约束可以是列约束或表约束: y 列约束被指定为列定义的一部分,并且仅适用于那个列(前面的score表中的约束 就是列约束)。 y 表约束的声明与列的定义无关,可以适用于表中一个以上的列。 261 第9章 Chapter 09 数据库完整性 当一个约束中必须包含一个以上的列时,必须使用表约束。例如,如果一个表的主键 内有两个或两个以上的列,则必须使用表约束将这两列加入主键内。假设有一个表记录工 厂内的一台计算机上所发生的事件。假定有几类事件可以同时发生,但不能有两个同时发 生的事件属于同一类型。这一点可以通过将type列和time列加入双列主键内来强制执行: CREATE TABLE factory_event (event_type int, event_time datetime, event_site char(50), event_desc char(1024), CONSTRAINT event_key PRIMARY KEY (event_type, event_time) ) 9.3 默认值 如果在插入行时没有指定列的值,则默认值指定列中所使用的值。默认值可以是任何 取值为常量的对象。 在SQL Server中,有两种使用默认值的方法: y 在创建表时,指定默认值。如果使用企业管理器,则可以在设计表时指定默认值。 如果使用Transact-SQL语言,则在CREATE TABLE语句中使用DEFAULT子句。这 是首选的方法,也是定义默认值比较简洁的方法。 y 使用CREATE DEFAULT语句创建默认对象,然后使用存储过程sp_bindefault将该 默认对象绑定到列上。这是向前兼容的方法。 9.3.1 在创建表时指定默认值 在使用SQL Server Management Studio创建表时,可以在输入字段名称后,设定该字段 的默认值,如图9.1所示。 图 9.1 设定默认值 如果使用Transact语言,则可以使用DEFAULT子句。这样在使用INSERT和UPDATE 语句时,如果没有提供值,则默认值会提供值。 可以在此指定c1 字段的默认值 新概念 SQL Server 2005 教程 262 例如,下面在test数据库中创建一个datetest表,其中c2指定默认值为当前日期: USE test GO CREATE TABLE datetest( c1 int, c2 datetime DEFAULT (getdate()) ) 然后插入一行数据: INSERT datetest(c1) VALUES(1) SELECT * FROM datetest 执行结果如下: c1 c2 --- --------------------------------- 1 2007-08-10 14:43:13.153 可看到,在上面插入数据中,只给定了c1字段的值,c2自动使用默认值,这里默认值 是使用getdate()函数来获取当前日期。 同样,可以给bookdb数据库中的orderform表中的order_date字段加上默认值: USE bookdb GO ALTER TABLE orderform ADD CONSTRAINT DateDflt DEFAULT getdate() FOR order_date 上面的SQL语句中,DateDflt表示DEFAULT约束的名字。 9.3.2 使用默认值对象 默认值对象是单独存储的,删除表的时候,DEFAULT约束会自动删除,但是默认值对 象不会被删除。另外,创建默认值对象后,需要将其绑定到某列或者用户自定义的数据类 型上。 1. 创建默认值对象 创建默认值对象可以使用CREATE DEFAULT语句,在SQL Server 2005中,不再提供 图形界面的默认值对象的创建方式。 CREATE DEFAULT语句的语法格式如下: CREATE DEFAULT default AS constant_expression 其中各参数含义如下: y default 默认值的名称。默认值名称必须符合标识符的规则。可以选择是否指定默 认值所有者名称。 y constant_expression 只包含常量值的表达式(不能包含任何列或其他数据库对象 263 第9章 Chapter 09 数据库完整性 的名称)。可以使用任何常量、内置函数或数学表达式。字符和日期常量用单引 号(')引起来;货币、整数和浮点常量不需要使用引号。二进制数据必须以0x开 头,货币数据必须以美元符号($)开头。默认值必须与列数据类型兼容。 例如,使用下面的SQL语句也可以创建address_default默认值对象: USE bookdb GO CREATE DEFAULT address_default AS '无' GO 2. 绑定默认值对象 默认值对象创建后不能使用,必须首先将其绑定到某列或者用户自定义的数据类型上。 这可以使用sp_bindefault存储过程来完成。 sp_bindefault存储过程的语法格式如下: sp_bindefault [ @defname = ] 'default' , [ @objname = ] 'object_name' [ , [ @futureonly = ] 'futureonly_flag' ] 其中各参数含义如下: y [@defname =] 'default' 由CREATE DEFAULT语句创建的默认值对象的名称。 default的数据类型为nvarchar(776),无默认值。 y [@objname =] 'object_name' 要绑定默认值的表和列名称或用户定义的数据类型。 object_name的数据类型为nvarchar(517),无默认值。如果object_name没有采取 table.column格式,则认为它属于用户定义数据类型。默认情况下,用户定义数据 类型的现有列继承default,除非默认值直接绑定到列中。默认值无法绑定到 timestamp数据类型的列、带IDENTITY属性的列或者已经有DEFAULT约束的列。 y [@futureonly =] 'futureonly_flag' 仅在将默认值绑定到用户定义的数据类型时才 使用。futureonly_flag的数据类型为varchar(15),默认值为NULL。将此参数设置为 futureonly时,它会防止现有的属于此数据类型的列继承新的默认值。当将默认值 绑定到列时不会使用此参数。如果futureonly_flag为NULL,那么新默认值将绑定 到用户定义数据类型的任一列,条件是此数据类型当前无默认值或者使用用户定 义数据类型的现有默认值。 例如,上面将address_default默认值对象绑定到authors表的address列上的操作过程可以 使用下面的SQL语句来完成: USE bookdb EXEC sp_bindefault 'address_default', 'authors.address' 3. 重命名默认值对象 和其他的数据库对象一样,也可以重命名默认值对象。重命名默认值对象也是使用 sp_rename存储过程来完成的,请参考前面的介绍。 使用企业管理器也可以重命名默认值对象,只需选择要重命名的默认值对象,然后右 新概念 SQL Server 2005 教程 264 击鼠标,执行“重命名”命令,输入新的默认值对象名称后按Enter键即可。 4. 解除默认值对象的绑定 解除绑定可以使用sp_unbindefault存储过程,其语法格式如下: sp_unbindefault [@objname =] 'object_name' [, [@futureonly =] 'futureonly_flag'] 其中各参数含义如下: y [@objname =] 'object_name' 是要解除默认值绑定的表和列或者用户定义数据类 型的名称。当为用户定义数据类型解除默认值绑定时,所有属于该数据类型并具 有相同默认值的列也同时解除默认值绑定。对属于该数据类型的列,如果其默认 值直接绑定到列上,则该列不受影响。 y [@futureonly =] 'futureonly_flag' 仅用于解除用户定义数据类型默认值的绑定。当 参数futureonly_flag为futureonly时,现有的属于该数据类型的列不会失去指定默认 值。 提 示 由于一列或者用户定义数据类型只能同时绑定一个默认值对象,所以解除绑定时, 不需要再指定默认值对象的名称。另外,如果要查看默认值的文本,可以以该默认值对象 的名称为参数执行存储过程sp_helptext。 例如,下面的SQL语句解除authors表address列上的默认值绑定: USE bookdb EXEC sp_unbindefault 'authors.address' 5. 删除默认值对象 在删除默认对象之前,首先要确认默认对象已经解除绑定。删除默认对象使用DROP DEFAULT语句,其语法格式如下: DROP DEFAULT { default } [ , …n ] 其中default是现有默认值的名称。若要查看现有默认值的列表,可以执行sp_help存储 过程。n是表示可以指定多个默认值的占位符。 例如,下面的SQL语句判断是否存在address_default默认值对象,如果存在,则删除该 默认值对象: USE bookdb IF EXISTS (SELECT name FROM sysobjects WHERE name = 'address_default' AND type = 'D') DROP DEFAULT address_default GO 265 第9章 Chapter 09 数据库完整性 注 意 DROP DEFAULT语句不适用于DEFAULT约束。如果要除去DEFAULT约束,则应该 使用ALTER TABLE语句。 9.4 规则 规则限制了可以存储在表中或者用户定义数据类型的值,它可以使用多种方式来完成 对数据值的检验,可以使用函数返回验证信息,也可以使用关键字BETWEEN、LIKE和IN 完成对输入数据的检查。 当将规则绑定到列或者用户定义数据类型时,规则将指定可以插入到列中的可接受的 值。规则是作为一个独立的数据库对象存在,表中每列或者每个用户定义数据类型只能和 一个规则绑定。 注 意 规则是一个向后兼容的功能,用于执行一些与CHECK约束相同的功能。CHECK约束 是用来限制列值的首选标准方法。CHECK约束比规则更简明,一个列只能应用一个规则, 但是却可以应用多个CHECK约束。CHECK约束作为CREATE TABLE语句的一部分进行指 定,而规则以单独的对象创建,然后绑定到列上。 和默认对象类似,规则只有绑定到列或者用户定义数据类型上才能起作用。如果要删 除规则,则应确定规则已经解除绑定。 9.4.1 创建规则 创建规则使用CREATE RULE语句,其语法格式如下: CREATE RULE rule AS condition_expression 其中各参数含义如下: y rule 是新规则的名称。规则名称必须符合标识符规则。可以选择是否指定规则所 有者的名称。 y condition_expression 是定义规则的条件。规则可以是WHERE子句中任何有效的 表达式,并且可以包含诸如算术运算符、关系运算符和谓词(如IN、LIKE、 BETWEEN)之类的元素。规则不能引用列或其他数据库对象。可以包含不引用数 据库对象的内置函数。 condition_expression包含一个变量。每个局部变量的前面都有一个@符号。该表达式引 用通过UPDATE或INSERT语句输入的值。在创建规则时,可以使用任何名称或符号表示值, 但第一个字符必须是@符号。 例如,下面的SQL语句创建一个名为score_rule的规则,限定输入的值必须在0~100之间: USE test 新概念 SQL Server 2005 教程 266 GO CREATE RULE score_rule AS @score BETWEEN 0 and 100 而下面创建的规则将输入到该规则所绑定的列中的实际值限制为只能是该规则中列出 的值: USE test GO CREATE RULE list_rule AS @list IN ('1997', '1997', '1996') 也可以使用LIKE来创建一个模式规则,即遵循某种格式的规则。例如,要使该规则指 定任意两个字符的后面跟一个连字符和任意多个字符(或没有字符),并以1~6之间的整数 结尾,则可以使用下面的SQL语句: USE test GO CREATE RULE pattern_rule AS @value LIKE '__-%[1-6]' 9.4.2 绑定规则 要使用规则,必须首先将其和列或者用户定义数据类型绑定。可以使用sp_bindrule存 储过程,也可以使用企业管理器。 使用企业管理器绑定规则的操作步骤和绑定默认对象的操作步骤相同,而sp_bindrule 存储过程的语法格式为: sp_bindrule [ @rulename = ] 'rule' , [ @objname = ] 'object_name' [ , [ @futureonly = ] 'futureonly_flag' ] 各参数含义和sp_bindefault存储过程相同。例如,下面的SQL语句可以将score_rule规则 绑定到score表的score列上: USE test EXEC sp_bindrule 'score_rule', 'score.score' 规则必须与列的数据类型兼容。规则不能绑定到text、image或timestamp列。一定要用 单引号(')将字符和日期常量引起来,在二进制常量前加0x。例如,不能将“@value LIKE A%”用作数字列的规则。如果规则与其所绑定的列不兼容,SQL Server将在插入值时(而 不是在绑定规则时)返回错误信息。 对于用户定义数据类型,只有尝试在该类型的数据库列中插入值,或更新该类型的数 据库列时,绑定到该类型的规则才会激活。因为规则不检验变量,所以在向用户定义数据 类型的变量赋值时,不要赋予绑定到该数据类型的列的规则所拒绝的值。 注 意 未解除绑定的规则,如果再次将一个新的规则绑定到列或者用户定义数据类型时, 旧的规则将自动被解除,只有最近一次绑定的规则有效。而且,如果列中包含CHECK约 束,则CHECK约束优先。 267 第9章 Chapter 09 数据库完整性 9.4.3 删除规则 对于不再使用的规则,可以使用DROP RULE语句删除。要删除规则首先要解除对该规 则的绑定,解除规则的绑定可以使用sp_unbindrule存储过程。 sp_unbindrule存储过程的语法格式如下: sp_unbindrule [@objname =] 'object_name' [, [@futureonly =] 'futureonly_flag'] 参数和sp_unbinddefault存储过程的参数含义相同。 例如,要解除绑定到score表的score列上的规则,可以使用下面SQL语句: USE test EXEC sp_unbindrule 'score.score' 解除规则的绑定后,就可以使用DROP RULE语句删除,其语法格式如下: DROP RULE { rule } [ , …n ] 例如,要删除规则score_rule,可以使用下面的SQL语句: DROP RULE score_rule 9.5 存储过程 存储过程是SQL语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单 元处理。存储过程存储在数据库内,可由应用程序通过一个调用执行,而且允许用户声明 变量、有条件执行以及其他强大的编程功能。存储过程可以使对数据库的管理,以及显示 关于数据库及其用户信息的工作容易得多。 存储过程可包含程序流、逻辑以及对数据库的查询。它们可以接受参数、输出参数、 返回单个或多个结果集以及返回值。 可以出于任何使用SQL语句的目的来使用存储过程,它具有以下优点: y 可以在单个存储过程中执行一系列SQL语句。 y 可以从自己的存储过程内引用其他存储过程,这可以简化一系列复杂语句。 y 存储过程在创建时即在服务器上进行编译,所以执行起来比单个SQL语句快,而 且能减少网络通信的负担。 9.5.1 创建存储过程 要使用存储过程,首先要创建一个存储过程。可以使用Transact-SQL语言的CREATE PROCEDURE语句,也可以使用SQL Server Management Studio来完成。 1. 使用 CREATE PROCEDURE 语句创建 CREATE PROCEDURE语句的语法格式为: CREATE PROC [ EDURE ] procedure_name [ ; number ] 新概念 SQL Server 2005 教程 268 [ { @parameter data_type } [ VARYING ] [ = default ] [ OUTPUT ] ] [ , …n ] [ WITH { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ] [ FOR REPLICATION ] AS sql_statement […n ] 其中各参数含义如下: y procedure_name 新存储过程的名称。 y ;number 是可选的整数,用来对同名的过程分组,以便用一条DROP PROCEDURE 语句即可将同组的过程一起除去。例如,名为orders的应用程序使用的过程可以命 名为orderproc;1、orderproc;2等。DROP PROCEDURE orderproc语句将除去整个组。 如果名称中包含定界标识符,则数字不应包含在标识符中,只应在procedure_name 前后使用适当的定界符。 y @parameter 过程中的参数。在CREATE PROCEDURE语句中可以声明一个或多 个参数。用户必须在执行过程时提供每个所声明参数的值(除非定义了该参数的 默认值)。存储过程最多可以有2100个参数。 y data_type 参数的数据类型。所有数据类型(包括text、ntext和image)均可以用作 存储过程的参数。不过,cursor数据类型只能用于OUTPUT参数。如果指定的数据 类型为cursor,也必须同时指定VARYING和OUTPUT关键字。 y VARYING 指定作为输出参数支持的结果集(由存储过程动态构造,内容可以变 化)。仅适用于游标参数。 y default 参数的默认值。如果定义了默认值,不必指定该参数的值即可执行过程。 默认值必须是常量或NULL。 y OUTPUT 表明参数是返回参数。该选项的值可以返回给EXEC[UTE]。使用 OUTPUT参数可将信息返回给调用过程。 y {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION} RECOMPILE表 明SQL Server不会缓存该过程的计划,该过程将在运行时重新编译。ENCRYPTION 表示SQL Server加密syscomments表中包含CREATE PROCEDURE语句文本的条 目。 y FOR REPLICATION 指定不能在订阅服务器上执行为复制创建的存储过程。 y sql_statement 过程中要包含的任意数目和类型的Transact-SQL语句。但是有一些 限制。 例如,下面创建一个简单的存储过程bookinfopro,用于检索书籍的名称、价格和出版 社: USE bookdb --判断bookinfopro存储过程是否存在,若存在,则删除 IF EXISTS (SELECT name FROM sysobjects WHERE name = 'bookinfopro' AND type = 'P') DROP PROCEDURE bookinfopro 269 第9章 Chapter 09 数据库完整性 GO USE bookdb GO --创建存储过程bookinfopro CREATE PROCEDURE bookinfopro AS SELECT book_name,price,publisher FROM book GO 通过下述SQL语句执行该存储过程: EXECUTE bookinfopro 执行结果如图9.2所示。 创建存储过程时应该注意下面几点: y 存储过程的最大大小为128MB。 y 用户定义的存储过程只能在当前数据库中创建(临时过程除外,临时过程总是在 tempdb中创建)。 y 在单个批处理中,CREATE PROCEDURE语句不能与其他Transact-SQL语句组合使 用。 y 存储过程可以嵌套使用,在一个存储过程中可以调用其他的存储过程。嵌套的最 大深度不能超过32层。 y 存储过程如果创建了临时表,则该临时表只能用于该存储过程,而且当存储过程 执行完毕后,临时表自动被删除。 y 创建存储过程时,sql_statement 不能包含下面的Transact-SQL 语句:SET SHOWPLAN_TEXT 、 SET SHOWPLAN_ALL 、 CREATE VIEW 、 CREATE DEFAULT、CREATE RULE、CREATE PROCEDURE和CREATE TRIGGER。 SQL Server允许创建的存储过程引用尚不存在的对象。在创建时,只进行语法检查。 执行时,如果高速缓存中尚无有效的计划,则编译存储过程以生成执行计划。只有在编译 过程中才解析存储过程中引用的所有对象。因此,如果语法正确的存储过程引用了不存在 的对象,则仍可以成功创建;但在运行时将失败,因为所引用的对象不存在。 2. 使用 SQL Server Management Studio 创建 使用SQL Server Management Studio创建存储过程的操作步骤如下: 打开SQL Server Management Studio,打开“数据库”文件夹,并打开要创建存储 过程的数据库。 打开“可编程性”文件夹,然后右击“存储过程”文件夹,在打开的快捷菜单中, 执行“新建存储过程”命令。此时,右侧窗口显示了CREATE PROCEDURE语句的框架, 可以修改要创建的存储过程的名称,然后加入存储过程所包含的SQL语句,如图9.3所示。 图 9.2 存储过程的执行结果 新概念 SQL Server 2005 教程 270 图 9.3 新建存储过程 输入完成后,单击工具栏上的“执行”按钮,可以立即执行SQL语句以创建存储 过程。也可以单击“保存”按钮保存该存储过程的SQL语句。 9.5.2 执行存储过程 执行存储过程使用EXECUTE语句,其完整语法格式如下: [ [ EXEC [ UTE ] ] { [ @return_status = ] { procedure_name [ ;number ] | @procedure_name_var } [ [ @parameter = ] { value | @variable [ OUTPUT ] | [ DEFAULT ] ] [ , …n ] [ WITH RECOMPILE ] 其中各参数含义如下: y @return_status 是一个可选的整型变量,保存存储过程的返回状态。这个变量在 用于EXECUTE语句前,必须在批处理、存储过程或函数中声明过。 y procedure_name 调用的存储过程名称。 y ;number 是可选的整数,用于将相同名称的过程进行组合,使得它们可以用一句 DROP PROCEDURE语句除去。 y @procedure_name_var 是局部定义变量名,代表存储过程名称。 y @parameter 是过程参数,在CREATE PROCEDURE语句中定义。参数名称前必 须加上符号(@)。 y value 是过程中参数的值。 y @variable 是用来保存参数或者返回参数的变量。 y OUTPUT 指定存储过程必须返回一个参数。该存储过程的匹配参数也必须由关 键字OUTPUT创建。使用游标变量作参数时使用该关键字。 271 第9章 Chapter 09 数据库完整性 y DEFAULT 根据过程的定义,提供参数的默认值。 y WITH RECOMPILE 强制编译新的计划。 下面就是执行简单存储过程的例子: EXECUTE bookinfopro 9.5.3 存储过程的参数 在创建和使用存储过程时,其参数是非常重要的。下面详细讨论存储过程的参数传递 和返回。 1. 使用参数 在调用存储过程时,有两种传递参数的方法。第一种是在传递参数时,使传递的参数 和定义时的参数顺序一致,对于使用默认值的参数可以用DEFAULT代替。 例如,下面的SQL 语句创建了一个用于向orderform表中插入记录的存储过程 Add_Order: USE bookdb GO CREATE PROC Add_Order ( @order_id int, @book_id int, @book_number int, @order_date datetime, @client_id int ) AS INSERT INTO orderform VALUES(@order_id,@book_id,@book_number,@order_date,@client_id) 则可以使用下面的SQL语句调用该存储过程: EXEC Add_Order 7,2,10,'99-05-06',2 另外一种传递参数的方法是采用“@order_id=7”的形式,此时,各个参数的顺序可以 任意排列。例如,上面的例子可以这样执行: EXEC Add_Order @order_id=7, @book_id=2, @book_number=10, @order_date ='99-05-06', @client_id =2 2. 使用默认参数 创建存储过程时,可以为参数提供一个默认值,默认值必须为常量或者NULL。 例如,下面的存储过程就指定了默认值: USE bookdb GO CREATE PROC Add_Author ( @author_id int, 新概念 SQL Server 2005 教程 272 @author_name char(8), @address char(50)='无', --默认值为'无' @telphone char(15)='无' --默认值为'无' ) AS INSERT INTO authors VALUES(@author_id,@author_name,@address,@telphone) 在上面创建的存储过程中,包含4个参数,其中@address和@telphone具有默认值“无”。 如果调用该存储过程: EXEC Add_Author 4,'张三' GO SELECT * FROM authors GO 执行结果如图9.4所示。 可以看到,对没有给定的参数@address和 @telphone使用了默认值。 3. 使用返回参数 在创建存储过程时,可以定义返回参数。在执行存储过程时,可以将结果返回给返回 参数。 例如,下面的存储过程Query_book返回两个参数@book_name和@price,分别代表了书 名和价格: CREATE PROC Query_book ( @book_id int, @book_name char(50) OUTPUT, @price float OUTPUT ) AS SELECT @price=price,@book_name=book_name FROM book WHERE book_id=@book_id 执行该存储过程,来查询book_id为2的书籍的名称和价格: DECLARE @price float DECLARE @book_name char(50) EXEC Query_book 2,@book_name OUTPUT,@price OUTPUT SELECT '书名'=@book_name,'价格'=@price GO 执行结果为: 书名 价格 ----------------------------------------- ----------- 3D Studio MAX实例精选 35.0 图 9.4 使用默认参数的存储过程的执行结果 273 第9章 Chapter 09 数据库完整性 4. 存储过程的返回值 存储过程在执行后都会返回一个整型值。如果执行成功,则返回0;否则返回-1~-99 之间的数值。也可以使用RETURN语句来指定一个返回值。 例如,下面的存储过程根据输入的参数来判断返回值: USE test GO CREATE PROC test_ret ( @input_int int =0 ) AS IF @input_int=0 RETURN 0 --如果输入的参数等于0,则返回0 IF @input_int>0 RETURN 1000 --如果输入的参数大于0,则返回1000 IF @input_int<0 RETURN -1000 --如果输入的参数等于0,则返回-1000 执行该存储过程: DECLARE @Ret_int int EXEC @Ret_int=test_ret -50 SELECT '返回值'=@Ret_int 执行结果为: 返回值 ---------- -1000 9.5.4 存储过程的查看、修改和删除 可以使用sp_helptext存储过程来查看存储过程的定义信息,例如,要查看test_ret存储过 程的定义信息,可以执行下面的SQL语句: EXEC sp_helptext test_ret 执行结果如下: Text ---------------------- CREATE PROC test_ret ( @input_int int =0 ) AS IF @input_int=0 RETURN 0 IF @input_int>0 RETURN 1000 IF @input_int<0 RETURN -1000 新概念 SQL Server 2005 教程 274 也可以使用SQL Server Management Studio管理平台来查看存储过程的定义信息,操作 步骤如下: 打开SQL Server Management Studio窗口,打开“数据库”文件夹,然后选择存储 过程所在的数据库。 依次选择“可编程性”|“存储过程”选项。 在右侧详细信息窗口中右击存储过程,执行“修改”命令,打开存储过程的SQL 语句窗口。 直接修改存储过程的定义。完成后,单击工具栏上的“执行”按钮,修改存储过 程。 不再需要存储过程时可将其删除。这可以通过SQL Server Management Studio来完成, 在要删除的存储过程中右击鼠标,然后执行“删除”命令,在弹出的“删除对象”对话框 中,单击“确定”按钮即可。也可以通过DROP PROCEDURE语句来完成。 例如,要删除test_ret存储过程,可执行下面的SQL语句: DROP PROCEDURE test_ret 如果另一个存储过程调用某个已删除的存储过程,则SQL Serve 2005会在执行该调用 过程时显示一条错误信息。但如果定义了同名和参数相同的新存储过程来替换已删除存储 过程,那么引用该过程的其他过程仍能顺利执行。例如,如果存储过程proc1引用存储过程 proc2,而proc2被删除,但又创建了另一个名为proc2的存储过程,现在proc1将引用这一新 存储过程,proc1也不必重新编译。 注 意 存储过程分组后,将无法删除组内的单个存储过程。删除一个存储过程会将同一组 内的所有存储过程都删除。 9.6 触发器 触发器是一种特殊类型的存储过程,它在指定的表中的数据发生变化时自动生效。唤 醒并调用触发器以响应INSERT、UPDATE或DELETE语句。触发器可以查询其他表,并可 以包含复杂的Transact-SQL语句。 触发器具有如下优点: y 触发器可通过数据库中的相关表实现级联更改。但是,通过级联引用完整性约束 可以更有效地执行这些更改。 y 触发器可以强制比用CHECK约束定义的约束更为复杂的约束。与CHECK约束不 同,触发器可以引用其他表中的列。例如,触发器可以使用另一个表中的SELECT 比较插入或更新的数据,以及执行其他操作,如修改数据或显示用户定义错误信 息。 y 触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。 275 第9章 Chapter 09 数据库完整性 y 一个表中的多个同类触发器(INSERT、UPDATE或DELETE)允许采取多个不同 的对策,以响应同一个修改语句。 y 确保数据规范化。使用触发器可以维护非正规化数据库环境中的记录级数据的完 整性。 9.6.1 创建触发器 在创建触发器前,应该考虑到下列问题: y CREATE TRIGGER语句必须是批处理中的第一个语句。将该批处理中随后的其他 所有语句解释为CREATE TRIGGER语句定义的一部分。 y 创建触发器的权限默认分配给表的所有者,且不能将该权限转给其他用户。 y 触发器为数据库对象,其名称必须遵循标识符的命名规则。 y 虽然触发器可以引用当前数据库以外的对象,但只能在当前数据库中创建触发器。 y 虽然不能在临时表或系统表上创建触发器,但是触发器可以引用临时表。不应引 用系统表,而应使用信息架构视图。 y 在含有用DELETE或UPDATE操作定义的外键的表中,不能定义INSTEAD OF和 INSTEAD OF UPDATE触发器。 y 虽然TRUNCATE TABLE语句类似没有WHERE子句(用于删除行)的DELETE语 句,但它并不会引发DELETE触发器,因为TRUNCATE TABLE语句没有记录。 y WRITETEXT语句不会引发INSERT或UPDATE触发器。 创建触发器时需要指定下面的选项: y 触发器的名称,必须遵循标识符的命名规则。 y 在其上定义触发器的表。 y 触发器将何时激发。 y 激活触发器的数据修改语句。有效选项为INSERT、UPDATE或DELETE。多个数 据修改语句可激活同一个触发器。例如,触发器可由INSERT或UPDATE语句激活。 y 执行触发操作的编程语句。 触发器可以由CREATE TRIGGER语句创建,其语法格式如下: CREATE TRIGGER trigger_name ON { table | view } [ WITH ENCRYPTION ] { { { FOR | AFTER | INSTEAD OF } { [DELETE] [,] [INSERT] [,] [UPDATE] } [ WITH APPEND ] [ NOT FOR REPLICATION ] AS [ { IF UPDATE ( column ) [ { AND | OR } UPDATE ( column ) ] […n ] | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask ) { comparison_operator } column_bitmask […n ] } ] 新概念 SQL Server 2005 教程 276 sql_statement […n ] } } 其中各参数含义如下: y trigger_name 是触发器的名称。 y Table | view 是在其上执行触发器的表或视图,有时称为触发器表或触发器视图。 y WITH ENCRYPTION 加密syscomments表中包含CREATE TRIGGER语句文本的 条目。 y AFTER 指定触发器只有在触发SQL语句中指定的所有操作都已成功执行后才激 发。所有的引用级联操作和约束检查也必须成功完成后才能执行此触发器。如果 仅指定FOR关键字,则AFTER是默认设置。不能在视图上定义AFTER触发器。 y INSTEAD OF 指定执行触发器而不是执行触发SQL语句,从而替代触发语句的操 作。 y { [DELETE] [,] [INSERT] [,] [UPDATE] } 是指定在表或视图上执行哪些数据修 改语句时将激活触发器的关键字。 y WITH APPEND 指定应该添加现有类型的其他触发器。 y NOT FOR REPLICATION 表示当复制进程更改触发器所涉及的表时,不应执行 该触发器。 y AS 是触发器要执行的操作。 y sql_statement 是触发器的条件和操作。 IF子句说明了触发器条件中的列值被修改时才触发触发器。判断列是否被修改,有如 下两种办法: (1)UPDATE ( column ) 参数为表或者视图中的列名称,说明这一列的数据是否被INSERT或者UPDATE操作修 改过。如果修改过,则返回TRUE;否则返回FALSE。 (2)COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask ) { comparison_operator } column_bitmask […n ] COLUMNS_UPDATED()检测指定列是否被INSERT或者UPDATE操作修改过。它返回 varbinary位模式,表示插入或更新了表中的哪些列。 COLUMNS_UPDATED函数以从左到右的顺序返回位,最左边的为最不重要的位。最 左边的位表示表中的第一列;向右的下一位表示第二列,依此类推。如果在表上创建的触 发器包含8列以上,则COLUMNS_UPDATED返回多个字节,最左边的为最不重要的字节。 在INSERT操作中COLUMNS_UPDATED将对所有列返回TRUE值,因为这些列插入了显式 值或隐性(NULL)值。 其后的几个选项的含义为: y bitwise_operator 是用于比较运算的位运算符。 277 第9章 Chapter 09 数据库完整性 y updated_bitmask 是整型位掩码,表示实际更新或插入的列。例如,表t1包含列C1、 C2、C3、C4和C5。假定表t1上有UPDATE触发器,若要检查列C2、C3和C4是否 都有更新,指定值14(对应二进制数为01110);若要检查是否只有列C2有更新, 指定值2(对应二进制数为00010)。 y comparison_operator 是比较运算符。使用等号(=)检查updated_bitmask中指定 的所有列是否都实际进行了更新。使用大于号(>)检查updated_bitmask中指定的 任一列或某些列是否已更新。 y column_bitmask 要检查列的整型位掩码,用来检查是否已更新或插入了这些列。 例如,下面是创建一个触发器,在插入记录时,自动显示表中的内容: USE test GO /*如果表T1存在,则删除*/ IF EXISTS(SELECT name FROM sysobjects WHERE name ='T1') DROP TABLE T1 GO /*创建表T1 */ CREATE TABLE T1( student_number int, student_name char(30) ) GO /*如果触发器Query_T1存在,则删除*/ IF EXISTS (SELECT name FROM sysobjects WHERE name = 'Query_T1' AND type = 'TR') DROP TRIGGER Query_T1 GO /*创建触发器Query_T1 */ CREATE TRIGGER Query_T1 ON T1 FOR INSERT, UPDATE, DELETE AS SELECT * FROM T1 GO 则在执行下面的语句时: INSERT T1 VALUES(985240,'llyyrr') 结果会显示出T1表中的记录: student_number student_name -------------- ----------------------- 985240 llyyrr 9.6.2 inserted表和deleted表 在触发器执行的时候,会产生两个临时表:inserted表和deleted表。它们的结构和触发 器所在的表的结构相同,SQL Server 2005自动创建和管理这些表。可以使用这两个临时的 驻留内存的表测试某些数据修改的效果及设置触发器操作的条件;然而,不能直接对表中 新概念 SQL Server 2005 教程 278 的数据进行更改。 提 示 SQL Server 2005不允许AFTER触发器引用inserted和deleted表中的text、ntext或image 列;但是允许INSTEAD OF触发器引用这些列。 deleted表用于存储DELETE和UPDATE语句所影响的行的副本。在执行DELETE或 UPDATE语句时,行从触发器表中删除,并传输到deleted表中。deleted表和触发器表通常 没有相同的行。 inserted表用于存储INSERT和UPDATE语句所影响的行的副本。在一个插入或更新事务 处理中,新建行被同时添加到inserted表和触发器表中。inserted表中的行是触发器表中新行 的副本。 在对具有触发器的表(触发器表)进行操作时,其操作过程如下: y 执行INSERT操作 插入到触发器表中的新行被插入到inserted表中。 y 执行DELETE操作 从触发器表中删除的行被插入到deleted表中。 y 执行UPDATE操作 先从触发器表中删除旧行,然后再插入新行。其中被删除的 旧行被插入到deleted表中,插入的新行被插入到inserted表中。 例如,下面的例子说明了inserted表和deleted表的作用: /*如果触发器Query_T1存在,则删除*/ IF EXISTS (SELECT name FROM sysobjects WHERE name = 'Query_T1' AND type = 'TR') DROP TRIGGER Query_T1 GO /*创建触发器Query_T1 */ CREATE TRIGGER Query_T1 ON T1 FOR INSERT, UPDATE, DELETE AS SELECT * FROM inserted SELECT * FROM deleted GO 如果此时执行下面的UPDATE语句: UPDATE T1 SET student_name='lyr' WHERE student_number=985240 执行结果为: student_number student_name -------------- ---------------- 985240 lyr student_number student_name --------------- ---------------- 985240 llyyrr 279 第9章 Chapter 09 数据库完整性 前面显示的是inserted表的内容,后面显示的是deleted表的内容。 9.6.3 使用触发器 在SQL Server 2005中,除了INSERT、UPDATE和DELETE的3种触发器外,还提供了 INSTEAD OF INSERT、INSTEAD OF UPDATE和INSTEAD OF DELETE触发器。下面就具 体的例子来介绍INSERT、UPDATE和DELETE的3种触发器的应用,而INSTEAD OF触发器, 限于篇幅,本书不做介绍。 1. INSERT 和 UPDATE 触发器 当向表中插入或者更新记录时,INSERT或者UPDATE触发器被执行。一般情况下,这 两种触发器常用来检查插入或者修改后的数据是否满足要求。例如,下面创建的check_score 触发器可用来检查插入的成绩是否在0~100之间: USE test GO /*检查是否存在score表,若存在,则删除*/ IF EXISTS (SELECT name FROM sysobjects WHERE name = 'score') DROP TABLE score GO /*创建score表*/ CREATE TABLE score ( student_no int, score int ) /*检查是否存在check_score触发器,若存在,则删除*/ IF EXISTS (SELECT name FROM sysobjects WHERE name = 'check_score' AND type = 'TR') DROP TRIGGER check_score GO /*在score表上创建check_score触发器*/ CREATE TRIGGER check_score ON score FOR INSERT, UPDATE AS DECLARE @score int SELECT @score=score FROM inserted IF @score<0 OR @score>100 BEGIN ROLLBACK RAISERROR('成绩必须在0~100之间!',16,1) END GO 如果此时插入一笔记录: INSERT score VALUES(985240,150) 则会出现下述提示信息: 新概念 SQL Server 2005 教程 280 消息50000,级别16,状态1,过程check_score,第11 行 成绩必须在0~100之间! 消息3609,级别16,状态1,第1 行 事务在触发器中结束。批处理已中止。 同样,在更新记录时,如果修改后的数据不满足要求,也会出现上述错误信息。 2. DELETE 触发器 DELETE触发器通常用于下面的情况: y 防止那些确实要删除,但是可能会引起数据一致性问题的情况,一般是为那些用 作其他表的外部键记录。 y 用于级联删除操作。 例如,score表中包含学生的学号和成绩,如果还存在一个T1表(在9.5.1小节中创建的 T1表),其中包含学生的学号和姓名,它们之间以学号相关联。 如果要删除T1表中的记录,则与该记录的学号对应的学生成绩也应该删除: /*向表score中插入一笔记录*/ INSERT score VALUES(985240,85) GO /*创建触发器delete_trigger*/ CREATE TRIGGER delete_trigger ON T1 FOR DELETE AS DELETE score WHERE score.student_no=deleted.student_number GO 此时,要删除T1表中的记录: DELETE T1 WHERE student_number=985240 则score表中对应的记录也被删除。如果使用SELECT语句来查询score表,将看到该记 录已经被删除。 9.6.4 修改触发器 修改触发器可以使用ALTER TRIGGER语句,其语法格式如下: ALTER TRIGGER trigger_name ON ( table | view ) [ WITH ENCRYPTION ] { { ( FOR | AFTER | INSTEAD OF ) { [ DELETE ] [ , ] [ INSERT ] [ , ] [ UPDATE ] } [ NOT FOR REPLICATION ] AS sql_statement […n ] } | { ( FOR | AFTER | INSTEAD OF ) { [ INSERT ] [ , ] [ UPDATE ] } [ NOT FOR REPLICATION ] 281 第9章 Chapter 09 数据库完整性 AS { IF UPDATE ( column ) [ { AND | OR } UPDATE ( column ) ] […n ] | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask ) { comparison_operator } column_bitmask […n ] } sql_statement […n ] } 各参数含义和CREATE TRIGGER语句相同,这里不再介绍。 9.6.5 删除触发器 除了使用SQL Server Management Studio删除触发器外,也可以使用DROP TRIGGER语 句来删除触发器。其语法格式如下: DROP TRIGGER { trigger } [ , …n ] 其中trigger是要删除的触发器名称。而n是表示可以指定多个触发器的占位符。 例如,要删除Query_T1触发器,则可以执行下面的SQL语句: DROP TRIGGER Query_T1 9.7 课堂演练 在BoardDb数据库的users表上创建触发器check_pwd,限制用户密码不低于6个字符。 参考SQL语句如下: USE BoardDb GO /*检查是否存在check_pwd触发器,若存在,则删除*/ IF EXISTS (SELECT name FROM sysobjects WHERE name = 'check_pwd' AND type = 'TR') DROP TRIGGER check_pwd GO /*在score表上创建check_pwd触发器*/ CREATE TRIGGER check_pwd ON users FOR INSERT, UPDATE AS DECLARE @pwd_len int SELECT @pwd_len=LEN(password) FROM inserted IF @ pwd_len <6 BEGIN ROLLBACK RAISERROR('密码至少要6个字符!',16,1) END GO 新概念 SQL Server 2005 教程 282 9.8 小结 数据完整性是指数据的正确性和完备性。在对数据进行操作时,数据的完整性可能会 遭到破坏。例如,在使用INSERT、DELETE和UPDATE语句进行操作时,可能会破坏数据 的完整性和一致性。 本章主要介绍了SQL Server提供的保持数据完整性的工具组件,包括约束、默认值、 规则、存储过程和触发器。它们分别可以实现不同类型的完整性。 约束是SQL Server 2005自动强制数据完整性的方式。SQL Server 2005提供了5种约束, 定义了关于列中允许值的规则,是强制完整性的标准机制。 默认值是如果在插入行时没有指定列的值,而默认使用的值。它表示的是一个域完整 性。它有两种实现方式:DEFAULT子句和默认值对象。DEFAULT子句是在创建表时使用 的选项,而默认值对象则是独立存在的数据库对象。在创建默认值对象后,需要将其绑定 到指定的列或者用户定义数据类型。 规则限制了可以存储在表中或者用户定义数据类型的值,它可以使用多种方式来完成 对数据值的检验。和默认值对象类似,在创建规则后,也需要将其和列或者用户定义数据 类型绑定。 存储过程是SQL语句和可选控制流语句的预编译集合,以一个名称存储并作为一个单 元处理。触发器则是一种特殊的存储过程,在对表执行INSERT、DELETE和UPDATE操作 时自动执行。使用存储过程和触发器可以有效地检查数据的有效性和数据的完整性、一致 性。 9.9 课后练习 9.9.1 简答题 (1)简述规则和CHECK约束的异同。 (2)使用默认值对象和规则的步骤类似,主要包括哪两个步骤? (3)触发器如何维护数据的完整性和一致性? (4)触发器和约束的区别有哪些? 9.9.2 操作题 (1)创建一个存储过程,用于检索订单信息,包括订单日期、客户名称、定购的书籍 名称、单价、数量和总价。 (2)创建一个触发器,用于在向author表修改或者插入数据时,检查telphone字段的长 度不大于13位(必须为区号+电话号码的格式,例如0312-12345678)。 第 10 章 数据备份、恢复和报表 10 Chapter 本章导读: ” 备份的基础知识 ” 备份设备的创建 ” 数据库的备份 ” 系统数据库的备份 ” 数据的恢复 ” 数据的导出 ” Reporting Services 10.1 SQL Server备份概述 在实际工作中,可能会遇到各种各样的故障,此时,备份和恢复数据库就显得非常重 要。SQL Server 2005提供了高性能的备份和还原功能。SQL Server备份和还原组件提供了 重要的保护手段,以保护存储在SQL Server数据库中的关键数据。实施计划妥善的备份和 还原策略可保护数据库,避免由于各种故障造成的损坏而丢失数据。 “备份”是数据的副本,用于在系统发生故障后还原和恢复数据。备份能够在发生故 障后还原数据。通过适当的备份,可以在媒体故障、用户错误、硬件故障或者自然灾难中 恢复数据。此外,数据库备份对于例行的工作(例如,将数据库从一台服务器复制到另一 台服务器、设置数据库镜像和文件归档等)也很有用。 图10.1中显示了由于灾难或其他原因丢失数据后,从数据库的完整备份还原数据的简 单情形。图中,数据库在t1、t2、…、t5等时刻对数据库进行了备份。在t5时刻后,数据发 生了损失,则可将数据库恢复到其最近一次的备份,即t5时刻的备份。备份点和故障点之 间的所有更新将全部丢失。但是通过添加日志备份,通常可将数据库还原到数据发生故障 的时刻,而不会丢失数据(如果使用的SQL Server版本支持时点恢复)。 SQL Server 2005提供了几种不同的备份类型:数据备份、差异备份以及在完整和大容 量日志恢复模式下的事务日志备份。 y 数据备份 是指包含一个或多个数据文件的完整映像的任何备份。数据备份会备 份所有数据和足够的日志,以便恢复数据。可对全部或部分数据库、一个或多个 文件进行数据备份。 新概念 SQL Server 2005 教程 284 y 差异备份 基于之前进行的数据备份,称为差异的“基准备份”。每种主要的数 据备份类型都有相应的差异备份。基准备份是差异备份所对应的最近完整或部分 备份。差异备份仅包含基准备份之后更改的数据区。在还原差异备份之前,必须 先还原其基准备份。 y 事务日志备份 也称为“日志备份”,包括了在前一个日志备份中没有备份的所 有日志记录。只有在完整恢复模式和大容量日志恢复模式下才会有事务日志备份。 图 10.1 数据的备份和恢复 事务在运行过程中,系统把事务开始、事务结束(包括COMMIT和ROLLBACK)以及 对数据库的插入、删除和修改等每一个操作作为一个登记记录(LOG记录)存放到日志文 件中。每个记录包括的主要内容有执行操作的事务标志、操作类型、更新前数据的旧值(对 插入操作而言此项为空值)以及更新后的新值(对删除操作而言此项为空值)。 登记的次序严格按照并行事务操作执行的时间次序,同时遵循“先写日志文件”的规 则,因为写一个修改到数据库中和写一个表示这个修改的LOG记录到日志文件值是两个不 同的操作,有可能在这两个操作之间发生故障。如果先写了数据库,而在事务日志中没有 登记下这个修改,以后就不可能恢复这个修改。因此,先写日志文件是出于一种安全的考 虑。 对于采用完整恢复模式或大容量日志恢复模式的数据库来说,定期的日志备份是其备 份策略的重要部分。事务日志保持不变,直到日志备份将其显式备份。每个事务备份都捕 获日志的不活动部分,然后截断该日志,删除不活动的部分。日志的活动部分以最早的未 提交的事务开始,并保留在日志文件中。为了保护已提交的事务并截断日志,有必要定期 进行日志备份。 10.2 备份数据 SQL Server提供两种方式备份数据库: y 备份数据库 对数据库中的数据和对象进行完全备份。 数据损失 数据库 还原到t5的数据库 数据库备份 时间 第10章 Chapter 10 数据备份、恢复和报表 285 y 备份事务日志 事务日志记录了上一次事务日志备份后的改变。 一种好的备份既有完全数据库备份,也有不断增加的事务日志备份。 注 意 备份是一种十分耗费时间和资源的操作,不能频繁操作。应该根据数据库使用情况 确定一个适当的备份周期。 10.2.1 备份设备 创建备份时,必须选择存放备份数据的备份设备。在SQL Server 2005中,可以将数据 库、事务日志和文件备份到磁盘和磁带设备上。 磁盘备份设备是硬盘或其他磁盘存储媒体上的文件,与常规操作系统文件一样。引用 磁盘备份设备与引用任何其他操作系统文件一样。可以在服务器的本地磁盘上或共享网络 资源的远程磁盘上定义磁盘备份设备,磁盘备份设备根据需要可大可小。最大的文件大小 相当于磁盘上可用的闲置空间。如果在网络上将文件备份到远程计算机上的磁盘,使用通 用命名规则名称(UNC),以\\Servername\Sharename\Path\File格式指定文件的位置。 提 示 建议不要将数据库或者事务日志备份到数据库所在的同一物理磁盘上的文件中。如 果包含数据库的磁盘设备发生故障,由于备份位于同一发生故障的磁盘上,因此无法恢复 数据库。 磁带备份设备的用法与磁盘设备大致相同,但是要注意下面一些问题: y 必须将磁带设备物理连接到运行SQL Server实例的计算机上。不支持备份到远程磁 带设备上。 y 如果磁带备份设备在备份操作过程中已满,但还需要写入一些数据,SQL Server 将提示更换新磁带并继续备份操作。 SQL Server使用物理设备名称或逻辑设备名称标识备份设备。物理备份设备是操作系 统用来标识备份设备的名称,如D:\Backup\book.bak。 逻辑备份设备是用来标识物理备份设备的别名或公用名称。逻辑设备名称永久地存储 在SQL Server内的系统表中。使用逻辑备份设备的优点是引用它比引用物理设备名称简单。 例如,逻辑设备名称可以是book_Backup,而物理设备名称则是D:\Backup\book.bak。 提 示 备份或还原数据库时,可以交替使用物理或逻辑备份设备名称。 可以在SQL Server Management Studio中或者使用sp_addump- device存储过程来创建一个备份设备。 1. 使用SQL Server Management Studio创建备份设备 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第10章\创建备份设 备.avi。 新概念 SQL Server 2005 教程 286 使用SQL Server Management Studio创建备份设备的操作步骤如下: 打开SQL Server Management Studio窗口,打开“服务器对象”文件夹。 右击“备份设备”文件夹,在打开的快捷菜单中,选择“新建备份设备”命令, 打开“备份设备”窗口,如图10.2所示。 图 10.2 创建备份设备 设置完成后,单击“确定”按钮,即可创建一个备份设备。 2. 使用sp_addumpdevice存储过程 sp_addumpdevice存储过程的语法格式如下: sp_addumpdevice [ @devtype = ] 'device_type' , [ @logicalname = ] 'logical_name' , [ @physicalname = ] 'physical_name' [ , { [ @cntrltype = ] controller_type | [ @devstatus = ] 'device_status' } ] 其中各参数的含义如下: y [@devtype =] 'device_type' 备份设备的类型,可以是disk、pipe和tape,它们分别 选择此单选钮 可以创建一个 磁带备份设备 直接输入备份 设备的物理名称。 输入备份设备的名称。 第10章 Chapter 10 数据备份、恢复和报表 287 表示磁盘、管道和磁带。 y [@logicalname =] 'logical_name' 备份设备的逻辑名称,该逻辑名称用于 BACKUP 和RESTORE语句中,logical_name的数据类型为sysname,没有默认值,并且不能 为NULL。 y [@physicalname =] 'physical_name' 备份设备的物理名称。 y [@cntrltype =] controller_type 指备份设备的类型,2表示磁盘,5表示磁带,6表示 管道。 y [@devstatus =] 'device_status' 指磁带备份设备对ANSI磁带标签的识别(noskip或 者skip),该选项决定是跳过或者读磁带上的ANSI头部信息。 例如,下面创建一个逻辑名为test_backup的备份设备: USE test EXEC sp_addumpdevice 'disk', 'test_backup', 'D:\test_backup.bak' 10.2.2 备份数据库 可以通过SQL Server Management Studio或者Transact-SQL语言的BACKUP语句来备份 数据库。使用SQL Server Management Studio,可以调度备份在一天中的任何时候发生。 提 示 SQL Server备份是动态的,也就是说,当用户使用数据库的时候,也可以进行备份。 但是,最好是在数据库没有进行大量的修改时执行备份,因为备份过程会使系统变慢。 在执行备份的时候,可以备份整个数据库,也可以只备份事务日志,单独备份事务日 志比备份整个数据库占用的存储空间要少,花费的时间也短。 1. 使用SQL Server Management Studio 下面以备份bookdb数据库为例,来介绍使用SQL Server Management Studio备份数据库 的一般操作步骤: 打开SQL Server Management Studio窗口,打开“数据库”文 件夹。 在要备份的数据库上右击鼠标,这里是bookdb。在打开的快 捷菜单中选择“任务”|“备份”命令,打开“备份数据库-bookdb” 窗口,如图10.3所示。 在“源”区域中,进行如下设置: y 在“数据库”下拉列表框中,可以选择要备份的数据库。这 里选择bookdb数据库。 y 在“备份类型”下拉列表框中,选择备份类型,这里选择“完整”选项。 y 在“备份组件”区域中,可以选择备份数据库或者备份文件和文件组。这里选择 “数据库”单选框,表示备份数据库。 在“备份集”区域中,进行如下设置: 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第10章\备份数 据库.avi。 新概念 SQL Server 2005 教程 288 y 在“名称”文本框中,输入备份的名称。 y 在“说明”文本框中,可以输入对该备份的说明。 y 在“备份集过期时间”区域中,设置备份集的过期时间。 图 10.3 “备份数据库”窗口 在“目标”区域中,可以选择备份到磁盘或备份到磁带。单击“添加”按钮,打 开“选择备份目标”对话框,如图10.4所示。在此对话框中可以选择备份设备,或者设置 一个文件名称来备份数据库。这里选择前面创建的备份设备BookBakDevice。 图 10.4 “选择备份目标”对话框 单击“确定”按钮,返回到“备份数据库-bookdb”窗口。 在“选择页”中,选择“选项”选项,可打开“选项”选项卡,如图10.5所示。 在此选项卡中,可以设置备份时的一些选项。 选择备份设备 第10章 Chapter 10 数据备份、恢复和报表 289 图 10.5 备份的选项设置 设置完成后,单击“确定”按钮,即可开始备份。备份完成后,会弹出一提示对 话框,如图10.6所示。 图 10.6 备份完成时的提示对话框 2. 使用BACKUP语句 BACKUP语句的语法格式如下: BACKUP DATABASE { database_name | @database_name_var } TO < backup_device >[ ,…n ] 其中database_name | @database_name_var为要备份的数据库名称;backup_device为备份 设备的名称。 例如,使用下面的SQL语句可以完成上面相同的功能: BACKUP DATABASE bookdb TO BookBakDevice 备份完成后,出现下述提示信息: 已为数据库'bookdb',文件'bookdb' (位于文件1 上)处理了216 页。 已为数据库'bookdb',文件'bookdb01' (位于文件1 上)处理了8 页。 已为数据库'bookdb',文件'sysft_BookDescripCatalog' (位于文件1 上)处理了141 页。 新概念 SQL Server 2005 教程 290 已为数据库'bookdb',文件'bookdb_log' (位于文件1 上)处理了1 页。 BACKUP DATABASE 成功处理了366 页,花费0.722s(4.143 MB/s)。 提 示 如果只备份事务日志,可以使用BACKUP LOG语句。它和BACKUP DATABASE都有 很多选项,用来设置备份的选项。 10.2.3 备份系统数据库 和用户数据库一样,系统数据库也要定期进行备份,尤其是master和msdb数据库。 master数据库包含了SQL Server配置的信息和服务器上所有其他数据库的有关信息,因 此应该定期备份该数据库。在SQL Server的配置或者它包含的数据库被改变后,都应该备 份master数据库。这些改变包括: y 在数据库上使用了CREATE或者ALTER语句。 y 使用了DBCC SHRINKDB命令。 y 添加或者删除登录账户或者改变了用户的权限。 y 建立、删除或者改变数据库或者备份设备的大小。 msdb数据库是SQL Server Agent服务使用的数据库。它是所有调度任务以及这些任务历 史的存储区。只要增加或者修改任务,增加或者修改自动备份工作,msdb数据库都会发生 改变。 10.3 数据的恢复 万一数据库被损坏,就可以使用备份来恢复数据库。恢复数据库是一个装载数据库的 备份,然后应用事务日志重建的过程。应用事务日志之后,数据库就会回到最后事务日志 备份之前的状态。 在数据库的恢复过程中,用户不能进入数据库,当数据库被恢复后,数据库中的所有 数据都被替换掉。 10.3.1 自动恢复 在每次启动时,SQL Server都会进行自动恢复,检查并且看一下是否有恢复工作需要 进行。自动恢复过程检查每个数据库的事务日志。这个过程搜索事务的开始和结束记录并 与数据库中的数据进行对比。在系统崩溃时没有完成的事务被回滚。 自动恢复过程以master数据库开始,然后移动到model数据库。SQL Server用model数据 库作为新建数据库的模板。model数据库被恢复之后,自动恢复过程消除tempdb数据库中的 所有对象。 提 示 tempdb数据库是SQL Server建立临时表和临时工作存储的地方。 第10章 Chapter 10 数据备份、恢复和报表 291 自动恢复接下来检查msdb数据库、pubs数据库。所有的系统数据库被恢复之后,自动 恢复才恢复用户数据库。系统数据恢复后,用户就能登录到服务器。 10.3.2 恢复用户数据库 在恢复用户数据库时,SQL Server自动执行安全检查,防止从不完整、不正确或者其 他数据库备份中恢复数据。 恢复数据库可以使用SQL Server Management Studio,也可以使用RESTORE语句。 1. 使用SQL Server Management Studio恢复数据库 使用SQL Server Management Studio恢复数据库的操作步骤如下: 打开SQL Server Management Studio窗口,打开“数据库”文 件夹。 由于数据库的还原操作是静态的,因此在还原数据库前,必 须限制其他用户对数据库进行其他操作。右击要还原的数据库,例如 bookdb,执行快捷菜单中的“属性”命令,打开“数据库属性-bookdb” 窗口。在“选择页”列表中,选择“选项”选项,打开“选项”选项 卡,在“限制选项”下拉列表中,选择SIGLE_USER,如图10.7所示。 图 10.7 “数据库属性-bookdb”窗口 单击“确定”按钮,此时弹出提示对话框,单击“确定”按钮即可。 在bookdb数据库上右击鼠标,在弹出的快捷菜单中,依次选择“任务”|“还原” |“数据库”命令,打开“还原数据库-bookdb”窗口,如图10.8所示。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第10章\恢复数 据库.avi。 新概念 SQL Server 2005 教程 292 图 10.8 “还原数据库-bookdb”窗口 在“还原的源”区域中,选择“源设备”单选按钮,然后单击其右侧的按钮,打 开“指定备份”对话框,如图10.9所示。 图 10.9 “指定备份”对话框 单击“确定”按钮,返回到“还原数据库-bookdb”窗口。 在“选择页”列表中,选择“选项”选项,打开“选项”选项卡,可以对还原的 选项进行设置。 设置完成后,单击“确定”按钮即可开始还原数据库。 完成后,系统会弹出提示框,提示还原已经成功。 2. 使用RESTORE语句 RESTORE语句的语法格式如下: RESTORE DATABASE { database_name | @database_name_var } [ FROM < backup_device > [ ,...n ] ] 选择现有数据库或者输入 一个新的数据库名称。 在下拉列表中选 择“备份设备”选项。 单击设置要还原 到的时间点。 单击“添加”按钮 可以添加备份设备。 第10章 Chapter 10 数据备份、恢复和报表 293 其中database_name | @database_name_var是将日志或整个数据库还原到的目的数据库。 指定还原操作要使用的逻辑或物理备份设备。 例如,下面的SQL语句用于恢复bookdb数据库: RESTORE DATABASE bookdb FROM Book_Backup 10.4 数据的导入和导出 SQL Server提供了一种很容易在SQL Server数据库或者非SQL Server数据库和另外一 个SQL Server数据库间转换数据的方法。通过SQL Server Management Studio,可以在不同 的数据库之间转换和传输数据。例如,可以将一个SQL Server数据库 中的数据转换到Microsoft Excel表中。操作步骤如下: 打开SQL Server Management Studio窗口,打开“数据库”文 件夹。 在要转换的数据库上右击鼠标,例如bookdb数据库。在打开 的快捷菜单上选择“任务”|“导出数据”命令,打开“SQL Server 导入和导出向导”对话框。 单击“下一步”按钮,向导提示选择数据源,如图10.10所 示。在“数据源”列表框中选择数据源类型,在“服务器”列表框中选择服务器,并设置 验证模式。在“数据库”下拉列表框中选择数据库。 图 10.10 选择数据源 单击“下一步”按钮,向导提示选择目标数据源,如图10.11所示。在“目标”下 选择数据源类型 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第10章\数据的导入 和导出.avi。 新概念 SQL Server 2005 教程 294 拉列表框中选择Microsoft Excel,表示将数据导出到Excel表中。然后在“Excel连接设置” 栏中,设置Excel文件的保存路径和Excel的版本。 图 10.11 选择目的数据 单击“下一步”按钮,向导提示用户指定表复制或者查询复制,如图10.12所示。 其中两个单选按钮的含义如下: 图 10.12 指定表复制或查询 y “复制一个或多个表或视图的数据”单选按钮 选择该项,表示直接复制表或者 视图的数据。 第10章 Chapter 10 数据备份、恢复和报表 295 y “编写查询以指定要传输的数据”单选按钮 选择该项,表示通过SQL查询语句 来获取要传输的数据。例如,可以通过SELECT查询语句来获取传输的数据。 选择“复制一个或多个表或视图的数据”单选按钮,然后单击“下一步”按钮, 向导提示“选择源表和源视图”,如图10.13所示。可以选择多个表或者视图,本例中选择 book表和book_info视图“书籍信息”。可以单击“预览”按钮来预览要导出的数据集合。 图 10.13 选择源表或者源视图 单击“下一步”按钮,向导提示用户是否保存包,如图10.14所示。其中两个复选 框的含义如下: 图 10.14 保存并执行包 y “立即执行”复选框 表示立即执行数据转换和传输。 y “保存SSIS包”复选框 可以保存SSIS包,以便用于复制或者调度以后执行。例 新概念 SQL Server 2005 教程 296 如,每周执行一次。 选择“立即执行”复选框,单击“下一步”按钮,出现“完成该向导”对话框, 如图10.15所示。在其中的列表框中显示了导出数据的源数据和目的数据,以及有关导出的 设置信息。如果不正确,可单击“上一步”按钮进行修改。 图 10.15 完成 SQL Server 导入/导出向导 单击“完成”按钮,开始转换和传输数据,并显示转换进度。完成后,单击“关 闭”按钮即可完成数据的传输。 提 示 导入数据的操作步骤和导出数据大致相同,在此不再介绍。 10.5 Reporting Services SQL Server 2005 Reporting Services提供有支持Web的企业级报告功能,以便创建能够 从多种数据源获取内容的报表,以不同格式发布报表,并集中管理安全性和订阅。 10.5.1 安装和配置Reporting Services 在使用Reporting Services以前,需要对其进行安装和配置。 1. 安装Reporting Services 参照第2章的安装操作步骤,在“要安装的组件”窗口中选择“Reporting Services”复 选框,然后依照安装向导的提示依次单击“下一步”按钮即可完成安装。 显示导出数据 的信息 第10章 Chapter 10 数据备份、恢复和报表 297 2. 配置报表服务器 报表服务器是Reporting Services的主要组件,它以Windows服务 和Web服务的形式实现,可以为处理和呈现报表提供优化的并行处理 基础结构。 在使用报表服务器前,需要对其进行验证和配置。操作步骤如下: 在“开始”菜单中,依次选择“所有程序”| Microsoft SQL Server 2005 |“配置工具”|“Reporting Services配置”选项。 此时,会弹出“选择报表服务器安装实例”对话框,在文本框内输入“计算机名 称”和“实例名”,如图10.16所示。 图 10.16 “选择报表服务器安装实例”对话框 单击“连接”按钮,进入“Reporting Services配置管理器”窗口,如图10.17所示。 在此窗口中,可以看到Reporting Services报表服务器的状态信息,包括“实例名”、“实例ID”、 “已初始化”和“服务状态”等。如果服务没有启动,可以单击“启动”按钮;如果单击 “停止”按钮,则停止服务。 图 10.17 “Reporting Services 配置报表管理器”窗口 在窗口左侧栏中,选择“报表服务器虚拟目录”选项,可以打开“报表服务器虚 拟目录”设置界面,如图10.18所示。 实讲实训 多媒体演示 多媒体演示参 见配套光盘中的\\ 视频\第10章\配置 报表服务器.avi。 新概念 SQL Server 2005 教程 298 图 10.18 “报表服务器虚拟目录”设置界面 如果需要通过Web形式访问报表服务器,则需要对报告服务器的虚拟目录进行设 置。单击“新建”按钮,打开“创建新的虚拟目录”对话框,如图10.19所示。 图 10.19 “创建新的虚拟目录”对话框 在“网站”下拉列表框中选择网站,然后在“虚拟目录”文本框中输入虚拟目录 的名称,单击“确定”按钮即可。 创建虚拟目录后,可以在浏览器中输入虚拟目录的地址,来访问Reporting Services 报表服务器,如图10.20所示。显示报表服务器安装成功。 图 10.20 通过 Web 方式访问报表服务器 第10章 Chapter 10 数据备份、恢复和报表 299 提 示 访问报表服务器的地址为:http:///ReportServer,其中computername 为计算机名称或者IP地址,如果是本地计算机,则可以直接输入localhost;ReportServer 则是默认的虚拟目录。 3. 配置报表服务管理器 报表服务管理器是基于Web方式的报告访问和管理工具,可 以通过浏览器通过HTTP连接从远程管理报表服务器实例,其操 作步骤如下: 在图10.18所示的窗口中,单击左侧窗口中的“报表管 理器虚拟目录”,打开报表管理器虚拟目录设置界面,如图10.21 所示。 图 10.21 报表管理器虚拟目录设置界面 单击“新建”按钮即可设置一个虚拟目录。 配置报告管理器的虚拟目录后,就可以通过Web方式来管理报表管理器实例,如 图10.22所示。 图 10.22 报表管理器实例 实讲实训 多媒体演示 多媒体演示参见配套 光盘中的\\视频\第10 章\配置报表服务管理 器.avi。 新概念 SQL Server 2005 教程 300 10.5.2 创建和设计报表 Reporting Services提供了报表设计器,用于创建和设计报表。报 表设计器是一组组件,它们是集成在Microsoft Visual Studio开发环境 中的图形化设计工具。 1. 创建报表服务器项目 在创建和设计报表以前,首先要创建报表服务器项目。操作步骤 如下: 在“开始”菜单中,依次选择“所有程序”| Microsoft SQL Server 2005 | Business Intelligence Development Studio选项,打开Microsoft Visual Studio开发环境,如图10.23所示。 图 10.23 Microsoft Visual Studio 开发环境 在“文件”菜单中,选择“新建”|“项目”命令,打开“新建项目”对话框,如 图10.24所示。 图 10.24 “新建项目”对话框 设置完成后,单击“确定”按钮,生成一个空白的报表服务器项目。 在“名称”、“位 置”和“解决方案名 称”文本框内输入相 应的内容。 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第10章\创建和设计 报表.avi。 选择“商业智能 项目”选项。 选择“报表服务器项目”选项。 第10章 Chapter 10 数据备份、恢复和报表 301 在“解决方案资源管理器”窗口中的“报表”上右击鼠标,在弹出的菜单中选择 “添加”|“新建项”命令,如图10.25所示。 图 10.25 选择“新建项”命令 此时,会打开“添加新项”对话框,在“模板”列表框中选择“报表”选项,如 图10.26所示。 图 10.26 选择“报表”选项 单击“添加”按钮,即可打开报表设计器窗口。其中包含3个选项卡:数据、布局 和预览。分别用于定义报表的数据源、设计报表的显示布局和预览报表。 2. 设置数据连接 创建报表项目后,需要进行数据源的设置,才能获取报表的内容。设置数据连接的操 作步骤如下: 在报表设计器的“数据”选项卡中,单击“数据集”下拉列表,选择“<新建数据 集...>”选项,如图10.27所示。 在打开的“数据源”对话框中,在“名称”文本框中输入数据源的名称;在“类 型”下拉列表中选择Microsoft SQL Server,如图10.28所示。 输入报表的名称。 新概念 SQL Server 2005 教程 302 图 10.27 选择“<新建数据集...>”选项 图 10.28 “数据源”对话框 单击“编辑”按钮,打开“连接属性”对话框, 如图10.29所示。在该对话框中,进行如下设置: y “服务器名”下拉列表框 输入服务器的名称。 如果是本地服务器,则可以输入localhost。 y “登录到服务器”选项区域 设置验证模式。如 果选择“使用SQL Server身份验证”单选按钮, 则还需要输入用户名和密码。 y “选择或输入一个数据库名”下拉列表框 选择 需要连接的数据库名称。 单击“确定”按钮,返回到“数据源”对话框。 此时,在“连接字符串”文本框中会出现如下字符串: Data Source=localhost;Initial Catalog=bookdb 其中,Data Source指定服务器名称;Initial Catalog指 图 10.29 “连接属性”对话框 第10章 Chapter 10 数据备份、恢复和报表 303 定要连接的数据库。 单击“确定”按钮,打开“输入数据 源凭据”对话框,输入用户名和密码,如图10.30 所示。该用户名和密码是用来登录到bookdb数 据库的用户名和密码。 单击“确定”按钮,返回到报表设计 器界面。 在“数据集”下面的文本框中输入查 询语句,该查询语句用于获取报表的内容。这里输入: Select *from book-info 单击“运行”按钮 ,在下面的结果集窗口中即会显示出查询结果,如图10.31 所示。 图 10.31 显示报表内容 3. 报表布局设计 数据设置完成后,需要进行报表的布局设计。操作步骤如下; 打开“布局”选项卡,在“工具箱”中双击“表”,在报表布局中添加一个表,如 图10.32所示。 提 示 如果窗口中没有显示“工具箱”面板,则可以在“视图”菜单中,选择“工具箱” 命令打开“工具箱”面板。 由于报表要显示的结果为5列,而添加的表默认为3列,因此,需要添加新列来满 足要求。在任一列头上右击鼠标,在打开的快捷菜单中,选择“在右侧插入列”命令,插 入一列。重复上面操作,再插入一列。 图 10.30 “输入数据源凭据”对话框 新概念 SQL Server 2005 教程 304 图 10.32 添加“表” 在第1行中输入报表表头,依次输入:“序号”、“书名”、“作者”、“价格”和“出 版社”。 从“数据集”窗口中,将book_id、book_name、author_name、price和publisher等 字段拖动至表的第2行中。此时的报表布局如图10.33所示。 图 10.33 报表布局 提 示 表第1 行定义了报表的表头,第2 行定义了数据的来源。例如第2 列为 =Fields!book_name.Value,表示获取的是数据源的book_name字段的内容。 4. 预览报表和输出 报表布局设置完成后,就可以预览报表和输出报表。操作步骤如下: 第10章 Chapter 10 数据备份、恢复和报表 305 打开“预览”选项卡,输入用户名和密码后,单击“查看报表”按钮,即可看到 报表的预览情况,如图10.34所示。如果效果不满意,可以再返回到“布局”选项卡进行调 整。 图 10.34 预览报表 要输出报表,可以单击“导出”按钮 ,打开一个下拉 列表,如图10.35所示。选择相应的命令即可。例如选择“Acrobat (PDF)文件”命令,在打开的对话框中设置输出文件的名称,单 击“保存”即可。 10.6 课堂演练 10.6.1 备份boarddb数据库 备份一下前面创建的boarddb数据库。操作步骤如下: 打开SQL Server Management Studio窗口,打开“服务器对象”文件夹。 首先创建一个备份设备。右击“备份设备”,在打开的快捷菜单中,执行“新建 备份设备”命令,打开“备份设备”窗口。在“设备名称”文本框中输入boarddb_bakdevice, 然后在“文件”文本框中设置保存的文件路径。 单击“确定”按钮,创建备份设备。 在“对象资源管理器”窗口中,右击要备份的boarddb数据库,执行“任务”|“备 份”命令。 依照10.2.2 节的操作,对boarddb 数据库进行完整备份。备份名称设置为 boarddb_bak;备份目标选择上面创建的备份设备。 设置完成后,单击“确定”按钮,即可开始备份。 10.6.2 制作bookdb数据库中订单的报表 利用Reporting Services创建bookdb数据库的报表,显示订购日期、客户名称、书名、 图 10.35 导出报表 新概念 SQL Server 2005 教程 306 单价、数量和总额。操作步骤如下: 在“开始”菜单中,依次选择“程序”| Microsoft SQL Server 2005 | Business Intelligence Development Studio | Microsoft Visual Studio开发环境。 在打开的窗口中的“文件”菜单中,选择“新建”|“项目”命令,打开“新建项 目”对话框。进行如下设置: y 在“项目类型”列表框中选择“商业智能项目”。 y 在“模板”列表框中选择“报表服务器项目”。 y 在“名称”文本框中输入OrderInfo。 y 在“位置”文本框中设置保存路径。 y 在“解决方案名称”文本框中输入OrderInfo。 单击“确定”按钮,生成一个空白的报表服务器项目。 在“解决方案资源管理器”窗口中,在“报表”上右击鼠标,在弹出的菜单中选 择“添加”|“新建项”命令,打开“添加新项”对话框,在“模板”列表框中选择“报表” 选项,并在“名称”文本框中输入报表的名称OrderInfo01.rdl。 单击“添加”按钮,打开报表设计器窗口。 在报表设计器的“数据”选项卡中,单击“数据集”下拉列表,选择“<新建数据 集...>”选项。 在打开的“数据源”对话框中,在“名称”文本框中输入数据源的名称 OrderDataSource;在“类型”下来列表中选择Microsoft SQL Server。 单击“编辑”按钮,打开“连接属性”对话框。在该对话框中,进行如下设置: y 在“服务器名”文本框中输入localhost。 y 选择“使用SQL Server身份验证”单选按钮,然后输入用户名boardacc,密码 boardacc。 y 选择“选择或输入一个数据库名”单选按钮,并在下面的下拉列表框中选择boarddb 数据库。 单击“确定”按钮,返回到“数据源”对话框。 单击“确定”按钮,打开“输入数据源凭据”对话框,输入用户名boardacc和密码 boardacc。 单击“确定”按钮,返回到报表设计器界面。 在“数据集”下面的文本框中输入查询语句: SELECT dbo.orderform.order_date AS 订购日期, dbo.book.book_name AS 书名, dbo.book.price AS 单价, dbo.orderform.book_number AS 数量, dbo.clients.client_name AS 客户名, dbo.orderform.book_number * dbo.book.price AS 总额 FROM dbo.book INNER JOIN dbo.orderform ON dbo.book.book_id = dbo.orderform.book_id INNER JOIN dbo.clients ON dbo.orderform.client_id = dbo.clients.client_id 单击“运行”按钮 ,查看显示结果。 第10章 Chapter 10 数据备份、恢复和报表 307 打开“布局”选项卡,在“工具箱”中双击“表”,在报表布局中添加一个表。 在任一列头上右击鼠标,在打开的快捷菜单中,选择“在右侧插入列”命令,插 入一列。重复上面操作,再插入两列。 在第1行中输入报表表头,依次输入:“订购日期”、“书名”、“单价”、“数 量”和“客户名”。 从“数据集”窗口中,将“订购日期”、“书名”、“单价”、“数量”和“客 户名”。等字段拖动至表的第2行中。 打开“预览”选项卡,输入用户名和密码后,单击“查看报表”按钮,即可看到 报表的预览情况。 单击“导出”按钮 ,进行相应选择以输出报表。 10.7 小结 本章主要介绍了SQL Server数据库的备份、还原和数据的转换输出,备份、还原可以 保证在数据库崩溃的情况下,快速地恢复数据库的工作。而数据的转换可以使SQL Server 与其他数据库交换数据。 应该经常备份数据库,以便在数据库出现故障时可以恢复。数据库备份的频率依赖于 修改数据库的数据总量,每次修改后都应该备份数据库。但是,备份要选择在没有进行大 量修改的情况下进行。 如果具有数据库的备份,则恢复一个崩溃的数据库相对来说是比较容易的。可以使用 SQL Server Management Studio或者RESTORE语句来恢复数据库。 利用SQL Server Management Studio的导入/导出数据工具,可以方便地与其他数据库进 行数据交换。 10.8 课后练习 10.8.1 选择题和简答题 (1)备份数据库的理由有: A. 数据库崩溃时恢复 B. 将数据从一个服务器转移到另外一个服务器 C. 记录数据的历史档案 D. 转换数据 (2)用来备份数据库是哪一个的命令: A. BACKUP DATABASE 新概念 SQL Server 2005 教程 308 B. sp_backupdatabase存储过程 C. BKDATABASE D. BACKUP DB (3)简单叙述备份系统数据库的原因。 10.8.2 操作题 (1)将bookdb数据库中的数据转换到Microsoft Access数据库管理系统中。 (2)将一个文本文件导入到SQL Server数据库中。 (3)将自己创建的数据库导出为文本文件。 第 11 章 使用 VB 开发 SQL Server 应用程序 11 Chapter 本章导读: ” 数据库程序开发概述 ” ODBC体系结构 ” ODBC数据源配置 ” OLE DB体系结构 ” ADO对象模型 ” 使用ADO数据控件开发简单的数据库应用程序 ” Visual Basic对数据库的操作 11.1 数据库应用程序开发概述 在实际应用中,数据库的应用最广泛。常用的数据库应用程序开发方式有下面几种。 1. 嵌入式SQL SQL是一种双重语言,它既是一种用于查询和更新的交互式数据库语言,又是一种应 用程序进行数据库访问时所采取的编程式数据库语言。嵌入式SQL语言就是将SQL语句直 接嵌入到程序的源代码中,与其他程序设计语言(例如C语言)语句混合。 嵌入式SQL的操作过程如下: 使用SQL的预编译程序将嵌入的SQL语句转换为能被程序设计语言的编译器识别 的函数调用。 使用程序设计语言的编译器对转换后的文件进行编译,然后连接为可执行程序。 2. ODBC数据库应用程序 ODBC(Open Database Connectivity,开放数据库系统互联)是微软公司开发和定义的 一套数据库访问标准,目前已经广泛地应用在数据库的程序设计和开发中。 ODBC提供了一种编程接口,可以使用一个ODBC应用程序访问多种数据库管理系统的 新概念 SQL Server 2005 教程 310 数据库,例如SQL Server、Oracle和DB2等。 ODBC提供了许多的API函数,用来对数据库进行操作。在应用程序中,可以直接使用 这些函数。而数据库的底层操作由各个数据库的驱动程序来完成。由于ODBC对数据库应 用程序具有良好的适应性和可移植性,所以ODBC在推出后就得到了很大的应用。 3. OLE DB数据库程序设计 OLE DB是微软开发的数据访问系统级编程接口,它也提供了对关系型数据库的访问, 并对ODBC进行了扩展。OLE DB主要用作所有数据库类型的标准界面。除了关系型数据库 外,OLE DB还提供了对各种各样数据源的访问,例如Excel电子表格、dBase的ISAM文件 和电子邮件等。使用OLE DB,用一个界面就可以访问许多不同的数据源。 对于不同的数据库程序设计方式,可以选择Visual C++、Visual Basic、Power Builder 等集成开发环境。下面几节在介绍ODBC、OLE DB以及基于OLE DB的ADO对象后,鉴于 Visual Basic的简单易用,以及使用的普遍性,将重点介绍Visual Basic中ADO的数据库程序 开发。 11.2 ODBC概述 ODBC是一种数据库访问API,它独立于数据库,建立在X/Open的结构化查询语言调用 层接口基础上。在使用ODBC开发数据库应用程序时,调用的是ODBC API函数和SQL语句。 而数据的底层操作则由不同类型数据库的驱动程序来完成。 11.2.1 ODBC体系结构 ODBC数据库应用程序由应用程序、驱动程序管理器、驱动程序和数据源4部分组成, 如图11.1所示。 图 11.1 ODBC 体系结构 数据库应用程序 驱动程序管理器 SQL Server 驱动程序 Oracle 驱动程序 FoxPro 驱动程序 DB2 驱动程序 …… SQL Server 数据源 Oracle 数据源 FoxPro 数据源 DB2 数据源 …… 311 第11章 Chapter 11 使用VB开发SQL Server应用程序 1. 应用程序 应用程序执行处理并调用ODBC函数。其主要任务如下: y 连接数据库。 y 提交SQL语句给数据库。 y 检索结果并处理错误。 y 提交或者回滚SQL语句的事务。 y 与数据库断开连接。 2. 驱动程序管理器 ODBC驱动程序管理器是一个驱动程序库,负责应用程序和驱动程序间的通信。对于 不同的数据源,驱动程序管理器将加载相应的驱动程序到内存中,并将后面的SQL请求传 送给正确的ODBC驱动程序。 3. 驱动程序 ODBC应用程序不能直接存取数据库,应用程序的操作请求需要由驱动程序管理器提 交给正确的驱动程序。而驱动程序负责将对数据库的请求操作传输到数据库管理系统 (DBMS),并把结果返回给驱动程序管理器。然后驱动程序管理器再将结果返回给应用程 序,由应用程序处理,并处理错误信息。 4. 数据源 数据源(Data Source Name,DSN)是连接数据库驱动程序与数据库管理系统(DBMS) 的桥梁,它定义了数据库服务器名称、登录名称和密码等选项。数据源分为3类:文件数据 源、系统数据源和用户数据源。最常用的是系统数据源。 11.2.2 配置ODBC数据源 使用ODBC编程之前,除了安装ODBC驱动程序外,还需要配置 ODBC数据源。配置ODBC数据源的操作步骤如下。 在控制面板中,将选择“管理工具”|“数据源(ODBC)” 命令,打开“ODBC数据源管理器”对话框,如图11.2所示。 该窗口用来设置ODBC数据源及其驱动程序等。各选项卡的功能如下: y 用户DSN 显示了当前登录用户使用的数据源清单。 y 系统DSN 显示了可以由系统中全部用户使用的系统数据源清单。 y 文件DSN 显示了允许连接到一个文件提供程序的数据源清单。 y 驱动程序 显示了所有已经安装的驱动程序。 y 跟踪 允许跟踪某个给定ODBC驱动程序的所有活动,并记录到日志文件。 y 连接池 用来设置连接ODBC驱动程序的等待时间。 y 关于 显示了由ODBC数据源管理器使用的动态连接库及其版本。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频\第11 章\配置 ODBC.avi。 新概念 SQL Server 2005 教程 312 图 11.2 “ODBC 数据源管理器”对话框 在“系统DSN”选项卡中,单击“添加”按钮,打开“创建新数据源”对话框, 如图11.3所示。 图 11.3 “创建新数据源”对话框 单击“完成”按钮,打开“Microsoft ODBC SQL Server DSN配置”对话框,如图 11.4所示。 图 11.4 “Microsoft ODBC SQL Server DSN 配置”对话框 单击“下一步”按钮,系统提示选择验证模式,如图11.5所示。 添加一个系 统数据源 删除一个系统 数据源 对选择的系统数 据源进行配置 选择SQL Server驱动 程序。 输入新的数 据源的名称。 输入新数据 源的说明。 选 择 SQL Server 服务器。 313 第11章 Chapter 11 使用VB开发SQL Server应用程序 图 11.5 选择验证模式 单击“下一步”按钮,系统提示用户设置默认数据库等选项,如图11.6所示。 图 11.6 设置连接的默认数据库 其余几个复选框的含义如下: y 为预定义的SQL语句创建临时存储过程,并删除该存储过程 该复选框允许使用 SQLPrepare函数时,创建一个临时存储过程,该选项只能用于SQL Server 6.5数据 库。 y 使用ANSI引用的标识符 选择该项,数据库源与SQL Server服务器连接时,将打 开QUOTED_IDENTIFIRES选项。 y 使用ANSI的空值、填充及警告 选择该复选框,数据源与SQL Server服务器连接 时,将打开ANSI_NULLS、ANSI_WARNINGS和ANSI_PADDINGS选项。 y 若主SQL Server不可用,请使用故障转移SQL Server 该选项允许备份SQL Server 系统,以防主SQL Server系统失败。 保持默认设置,单击“下一步”按钮,系统提示用户设置驱动程序使用的语言、 字符集区域设置和日志文件等,如图11.7所示。 如果选择SQL Server验证,则需 要输入登录账户和 密码 新概念 SQL Server 2005 教程 314 图 11.7 设置驱动程序使用的语言、字符集区域设置和日志文件等 单击“完成”按钮,出现“ODBC Microsoft SQL Server安装”对话框,如图11.8 所示。其中显示了新数据源的配置选项。 图 11.8 “ODBC Microsoft SQL Server 安装”对话框 单击“测试数据源”按钮,打开“SQL Server ODBC数据源测试”对话框,其中 显示了SQL Server的驱动程序版本号,并显示测试是否成功的消息。单击“确定”按钮, 即可返回到“ODBC Microsoft SQL Server安装”对话框。 单击“确定”按钮,即可创建一个新的数据源。 提 示 如果更改了数据源的配置,可在“ODBC数据源管理器”窗口中单击“配置”按钮重 新对数据源进行配置。 11.3 OLE DB和ADO概述 OLE DB创建于OLE(对象的链接与嵌入)技术基础上,其来源被称为提供者(Provider), OLE DB的优点就是它可以和任何Visual Studio产品协同工作,例如Visual C++、Visual Basic 新数据源的配 置选项 315 第11章 Chapter 11 使用VB开发SQL Server应用程序 等。 ADO(ActiveX Data Objects)并不是访问数据的底层解决方案。OLE DB是使用ADO 的基础,ADO只是OLE DB提供的服务的漂亮包装。实际上,也可以直接使用OLE DB进行 数据库程序的开发,但是,使用ADO进行开发的速度要快得多。 11.3.1 OLE DB体系结构 微软定义了OLE DB的4个主要类型: y 数据提供者 使用OLE DB SDK(软件开发工具)创建OLE DB提供者的人。 y 数据消费者 访问数据库中信息的应用程序、系统驱动程序或者用户。 y 数据服务提供者 创建用以增强用户或者数据库管理员使用或者管理数据库能力 的独立应用程序。例如,查询分析器就是一个数据服务提供者。 y 部件开发者 创建应用程序模块或部件,以减少创建数据库应用程序所需的编码 工作。例如,Visual Basic中提供的ADO控件。 一般来说,OLE DB消费者通过OLE DB用户界面和OLE DB提供者来访问数据源,它 们之间的关系如图11.9所示。 图 11.9 OLE DB 消费者和提供者之间的关系 对于不同的OLE DB提供者,OLE DB提供不同级别的功能,但是它们都支持一个通用 的用户界面。和ODBC类似,不同的OLE DB数据源使用自己的OLE DB提供者,如图11.10 所示。 该图显示了应用程序通过ADO和OLE DB提供者来访问不同类型数据源的过程。例如, 使用Microsoft Excel OLE DB提供者可以访问Excel的电子表格数据。 提 示 实际上,ODBC和OLE DB是互补的,不能完全相互替换。它们并不是两种完全分离 的技术。ODBC OLE DB提供者允许用户通过OLE DB或者ADO调用ODBC提供的所有功 能。 应用程序(OLE DB消费者) OLE DB界面(例如ADO等) OLE DB提供者 数据源 新概念 SQL Server 2005 教程 316 图 11.10 应用程序通过 ADO 调用 OLE DB 的模型 11.3.2 ADO对象模型 ADO是一个OLE DB的消费者,它提供了对数据源的应用程序访问。另外,ADO是一 个OLE自动服务器,大多数兼容OLE的开发和脚本环境可以调用它。 使用ADO,可以编写通过OLE DB提供者对数据库中数据进行访问和操作的应用程序。 其优点就是易于使用,性能好,占用内存和磁盘空间少,并且支持基于客户机/服务器的 Web数据库应用程序。 提 示 ADO比DAO(Data Access Objects)和RDO(Remote Database Objects)的框架更简 单,更易于使用。 ADO的对象模型为层次结构,如图11.11所示。其中每个Connection、Command、 Recordset和Field对象都有Properties集合。 图 11.11 ADO 的层次对象模型 数据库应用程序 ADO ODBC的OLE DB 提供者(MSDASQL) SQL Server的OLE DB 提供者(SQLOLEDB) Excel的OLE DB 提供者 OLE DB 提供者 …… ODBC 驱动程序 ODBC数据源 SQL Server Excel电子 表格数据 其他 数据源 Connection Errors集合 Command Recordset Error Parameters集合 Parameter Fields集合 Field 317 第11章 Chapter 11 使用VB开发SQL Server应用程序 主要的ADO对象有3个:Connection、Command和Recordset。它们还包含许多子对象, 例如Field、Property、Parameter和Error等。ADO提供的对象如表11.1所示。 表11.1 ADO提供的对象及其功能 对象名称 功能描述 Connection 提供对数据库服务器的连接 Command 对数据库服务器提供数据查询 Recordset 由数据库服务器所返回的记录集合 Field 代表使用普通数据类型的数据的列 Property 代表由提供者定义的 ADO 对象的动态特性 Parameter 与命令相关的参数;命令对象的所有参数都包含在它的参数集合中 Error 包含与单个操作(涉及提供者)有关的数据访问错误的详细信息 除了上述对象外,ADO还提供了Errors、Parameters、Fields、Properties等集合,如表11.2 所示。 表11.2 ADO提供的集合及其功能 对象名称 功能描述 Errors 所有为响应单个连接错误而创建的 Error 对象 Parameters 所有与 Command 对象关联的 Parameter 对象 Fields 所有与 Recordset 对象关联的 Field 对象 Properties 所有与 Connection、Command、Recordset 或 Field 对象关联的 Property 对象 Connection对象能够建立数据库与应用程序之间的联系,在建立联系后,Command与 Recordset对象用来要求、存储或者更新数据,简单地说,可以把Connection对象比作拨打电 话的动作,在拨通电话后则通过Command和Recordset对象与远方的通话者通话。 Command对象主要担任数据库查询的角色,一般来说该请求是通过SQL语句来描述, 把欲请求的SQL语句字符串指定到Command对象内的CommandString属性,接着执行数据 库查询的动作。数据库服务器响应后,结果即存储在Recordset对象中。 在所有ADO对象中,Recordset对象功能最强大,由数据库服务器取得的数据集合就存 储在Recordset对象中。然后再利用程序语言来处理该Recordset对象中的记录。 Connection、Command、Recordset虽然是3个不同的对象,但是三者之间是息息相关、 互相牵连的。Command对象必须依赖于Connection对象,而Recordset对象则要视Connection 对象与Command对象的状态而定。至于Connection对象,则必须依赖数据库服务器的连接 情况了。 另外,ADO允许程序设计人员在程序的执行期间将不同已经建立的ADO对象做关联, 因此在实际编写程序代码时,可以先分别建立Command对象,然后利用Command对象的 ActiveConnection属性来关联某个已与数据库完成连接动作的Connection对象。同样, Recordset对象内部的ActiveConnection属性也可与已经建立连接的Connection对象关联。更 方便的是,可以传入连接描述字符串或者SQL语句给ActiveConnection属性,让Recordset对 新概念 SQL Server 2005 教程 318 象自动完成连接与请求的动作。ADO的功能与易于使用的特点,由此可见一斑。 提 示 由于OLE DB提供者所支持的功能不同,ADO对象的某些属性、方法或者集合可能无 效。 ADO的目标是访问、编辑和更新数据源,而编程模型体现了为完成该目标所必需的系 列动作的顺序。使用ADO进行编程的基本步骤如下: 连接到数据源。同时,可确定对数据源的所有更改是否已成功或没有发生。 指定访问数据源的命令,同时可带变量参数或优化执行。 执行命令。 如果这个命令使数据按表中的行的形式返回,则将这些行存储在易于检查、操作 或更改的缓存中。 适当情况下,可使用缓存行的更改内容来更新数据源。 提供常规方法检测错误(通常由建立连接或执行命令造成)。 关闭连接到的数据源。 11.4 使用VB开发SQL Server应用程序 Visual Basic 6.0成功地引入了功能强大的ADO作为新的数据访问标准,它包含SQL Server、Oracle、Access、ODBC和SNA服务器等OLE DB驱动程序。另外,Visual Basic 6.0 提供了一个ADO Data控件,使用该控件,可以很方便地实现数据库应用程序的绑定。 11.4.1 ADO的引用和查看 在Visual Basic中使用ADO之前,必须设置对ADO类库的引用。 ADO类库也称为ADO自动服务器。这就需要在Visual Basic开发环境 中设置对ADO OLE类库的引用。 在Visual Baisc中增加ADO引用的操作步骤如下。 启动Visual Basic 6.0,在“工程”菜单中,执行“引用”命 令,打开“引用”对话框,如图11.12所示。 在“可用的引用”列表框中,找到Microsoft ActiveX Data Objects 2.6 Library选项,并 选中前面的复选框。 提 示 Visual Basic 6.0提供了2.0、2.1、2.5、2.6等几个ADO版本,在使用时,可以根据需要 选择其中一个。 实讲实训 多媒体演示 多媒体演示参见 配套光盘中的\\视 频 \ 第 11 章 \ADO 的引用.avi。 319 第11章 Chapter 11 使用VB开发SQL Server应用程序 图 11.12 “引用”对话框 单击“确定”按钮,即可在Visual Basic中增加对ADO的引用。 如果要查看ADO提供的对象的属性、方法和集合等,可在“视图”菜单中,执行 “对象浏览器”命令,打开“对象浏览器”对话框,如图11.13所示。 图 11.13 “对象浏览器”对话框 11.4.2 使用ADO Data控件开发简单的数据库应用程序 使用ADO Data控件可以快速建立数据约束控件和数据源之间的联系,用户可以使用这 些约束控件将数据提供到用户界面上。 1. 添加ADO Data控件 在使用ADO Data控件之前,需要将其添加到工具箱中,操作步骤如下: 在“工程”菜单中,执行“部件”命令,打开“部件”对话框,如图11.14所示。 在Visual Basic中可 以引用的ADO类库 查 看 Conne- ction对象的属性、 方法等。 选择ADODB。 选择ADO中 的对象。 新概念 SQL Server 2005 教程 320 图 11.14 “部件”对话框 单击“确定”按钮,在Visual Basic的工具箱中,即可看到添加的ADO Data控件, 如图11.15所示。 图 11.15 ADO Data 控件 2. ADO Data控件的属性、方法和事件 为了实现对数据库的访问,ADO Data控件提供了几个属性。这些属性定义了与数据库 连接的方法,包括连接字符串、用户名称和密码等。ADO Data控件的主要属性及其含义如 表11.3所示。 除了与数据库连接所需的属性外,ADO Data控件还提供了用于对数据库进行操作的方 法和用于编程的事件。ADO Data控件的主要方法如表11.4所示,用于编程的主要事件如表 11.5所示。 表11.3 ADO Data控件的主要属性 属性 说明 ConnectionString 为一字符串,包含进行一个连接所需要的所有设置值 UserName 用户名称,该属性也可以在ConnectionString指定,若ConnectionString和UserName 同时指定,则ConnectionString的值将覆盖UserName中的值 Password 与UserName对应的密码,若ConnectionString也指定了密码,则ConnectionString 的值将覆盖Password中的值 RecordSource 指定记录来源,通常为一条SQL语句 Mode 决定使用记录集进行什么操作 添加的ADO Data控件 选择ADO数 据库控件。 321 第11章 Chapter 11 使用VB开发SQL Server应用程序 (续表) 属性 说明 CommandType 设置RecordSource属性是一条SQL语句、一个表的名称、一个存储过程或者一个 未知的类型 ConnectionTimeout 设置等待连接的时间,以秒为单位。若连接超时,则会返回一个错误信息 CursorLocation 指定游标的位置,是位于客户机还是服务器。该设置将影响到下面的设置 CursorType 返回的记录类型:静态、动态或者键集游标类型 MaxRecords 决定游标的大小,取决于所检索的记录的大小和计算机的可用资源 CacheSize 指定从游标中可以检索多少条记录 表11.4 ADO Data控件的主要方法 方法 说明 Refresh 更新集合中的对象,以便反映来自并特定于提供者的对象 UpdateRecord 此方法可以将约束控件上的数据写到数据库,使用此方法可以修改数据库中的 数据 UpdateControl 从控件的 ADO Recordset 对象中获取当前行,并在绑定到此控件的控件中显示 相应的数据 Close 用于关闭打开的对象,使用 Close 可以关闭 Connection 或者 Recordset 对象, 以便释放系统资源 表11.5 ADO Data控件的主要事件 事件 产生条件 WillMove 当执行 Recordset.Open、Recordset.MoveNext、Recordset.Move、 Recordset.MoveLast、Recordset.MoveFirst、Recordset.MovePrevious、 Recordset.Bookmark、Recordset.AddNew、Recordset.Delete、 Recordset.Requery、Recordset.Resync 方法时 MoveComplete 在 WillMove 事件之后 WillChangeField 在 Value 属性更改之前 FieldChangeComplete 在 WillChangeField 事件之后 WillChangeRecord 当执行 Recordset.Update、Recordset.Delete、Recordset.CancelUpdate、 Recordset.UpdateBatch、Recordset.CancelBatch 方法时 RecordChangeComplete 在 WillChangeRecord 事件之后 WillChangeRecordset 在执行 Recordset.Requery、Recordset.Resync、Recordset.Close、 Recordset.Open、Recordset.Filter 方法时 RecordsetChangeComplete 在 WillChangeRecordset 事件之后 InfoMessage 当数据提供者返回一个结果时 3. 创建简单的数据库应用程序 ADO Data控件使用Microsoft ActiveX数据对象(ADO)来快速建立数据绑定的控件和 新概念 SQL Server 2005 教程 322 数据提供者之间的连接。数据绑定控件是任何具有“数据源”属性的控件。数据提供者可 以是任何符合OLE DB规范的数据源。 在Visual Basic的“工具箱”中不少控件都可以作为数据绑定的控件,包括复选框、组 合框、图像、标签、列表框、图片框和文本框控件等。此外,Visual Basic还包括若干种数 据绑定的ActiveX控件,诸如DataGrid、DataCombo、Chart及DataList控件等。用户也可以创 建自己的数据绑定的ActiveX控件或从其他开发商购买控件。 通过在设计时设置一些属性,可以用最少的代码来创建一个 数据库应用程序。下面就创建一个简单的数据库应用程序,用来 查看书籍信息。其操作步骤如下: 在Visual Basic 6.0中创建一个新的工程,并将工程名称 设置为Book,窗体名称设置为frmBook,Caption属性设置为“书 籍信息窗口”。将工程保存为Book.vbp,将窗体保存为Book.frm。 确定添加了ADO类库的引用,并添加了ADO Data控件。将工具箱中的ADO Data 控件拖放到窗体中,将Name属性设置为Ado_Book,Align属性设置为2-vbAlignBottom,表 示将控件放置在窗体底部,此时的窗体如图11.16所示。 图 11.16 添加 ADO Data 控件后的窗体 确认ADO Data控件处于选中状态,然后在属性窗口选择ConnectionString属性,单 击后面带有省略号的按钮,打开“属性页”对话框,如图11.17所示。该对话框用来设置数 据源。 图 11.17 添加数据源 单击“确定”按钮,然后在属性页窗口中选择UserName属性,单击后面带有省略 ADO Data控件 单击可新建一个 ODBC数据源 选择一个 ODBC数据源book。 实讲实训 多媒体演示 多媒体演示参见配套 光盘中的\\视频\第11 章\ADOData控件.avi。 323 第11章 Chapter 11 使用VB开发SQL Server应用程序 号的按钮,打开“身份验证”选项卡,如图11.18所示。 图 11.18 设置用户名和密码 提 示 如果选择Password属性,然后单击后面带有省略号的按钮,同样可以设置用户名称 和密码。 单击“确定”按钮。然后选择RecordSource属性,单击后面带有省略号的按钮, 打开记录源设置对话框,如图11.19所示。在“命令类型”列表框中选择1 - adCmdText选项, 并在“命令文本”文本框中输入下述SQL语句: SELECT book.book_name AS 书名, authors.author_name AS 作者, book.price AS 价格, book.publisher AS 出版社 FROM authors INNER JOIN book ON authors.author_id = book.author_id 图 11.19 设置记录源 其中命令类型有下面几种类型: y 1 - adCmdText 文本类型命令,常用来输入进行书籍检索的SQL语句。 y 2 - adCmdTable 表类型命令。 y 4 - adCmdStroedProc 存储过程命令。 y 8 - adCmdUnknown 未知类型命令。 选择EOFAction属性,然后选择1 - adStayEOF选项,表示若当前数据是最后一个时, 输入进行检索 的SQL语句 输入用户名和 密码,这里指登录数 据库的登录账户。 选择记录源类型 新概念 SQL Server 2005 教程 324 如果单击ADO Data控件的向右箭头,则仍然维持最后一个记录。如果选择2 - adDoAddNew, 则单击向右箭头时,将自动添加一个新记录。 加入几个简单的约束控件,用来显示书籍信息,如图11.20所示。 图 11.20 加入约束控件后的窗体 几个约束控件的名称和属性设置如表11.6所示。 表11.6 约束控件的属性设置 约束控件 DataSource 属性 DataField 属性 Text1 Ado_Book 书名 Text2 Ado_Book 作者 Text3 Ado_Book 价格 Text4 Ado_Book 出版社 双击ADO Data控件,进入代码窗口。在对象列表框中选择Ado_Book,然后在过 程列表框中选择MoveComplete,如图11.21所示。 图 11.21 代码窗口 输入设置ADO Data控件的标题信息,完整代码如下: Private Sub Ado_Book_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset) Ado_Book.Caption = "当前书籍:" + Str(Ado_Book.Recordset.AbsolutePosition) + "/" + Str(Ado_Book.Recordset.RecordCount) End Sub 选 择 MoveComplete 过 程 选择Ado_Book对 象 325 第11章 Chapter 11 使用VB开发SQL Server应用程序 运行程序,可看到约束控件中显示出了书籍的信息。单击向右的箭头,则显示下 一笔记录,如图11.22所示。 图 11.22 程序运行界面 提 示 除了使用简单的约束控件显示所需信息外,还可以使用DataList(数据列表)、 DataCombo(数据组合)、DataGrid(数据网格)控件等来显示数据信息。 11.4.3 使用代码操纵数据库 使用ADO Data控件只能进行简单的数据库编程,用起来不太灵活。如果要自己控制记 录的显示和操作,可以使用代码进行数据库编程。使用代码进行编程的主要过程就是操纵 ADO的Connection、Recordset和Command三大对象的过程。 1. 使用Connection对象连接数据库 Connection对象代表与数据源进行的唯一会话。如果是客户端/服务器数据库系统,该 对象可以等价于到服务器的实际网络连接。 使用Connection对象的集合、方法和属性可执行下列操作: y 在打开连接前使用ConnectionString、ConnectionTimeout和Mode属性对连接进行配 置。 y 设置CursorLocation属性以便调用支持批更新的“客户端游标提供者”。 y 使用DefaultDatabase属性设置连接的默认数据库。 y 使用IsolationLevel属性为在连接上打开的事务设置隔离级别。 y 使用Provider属性指定OLE DB提供者。 y 使用Open方法建立到数据源的物理连接。使用Close方法终止连接。 y 使用Execute方法执行对连接的命令,并使用CommandTimeout属性对执行进行配 置。 y 可使用BeginTrans、CommitTrans和RollbackTrans方法以及Attributes属性管理打开 的连接上的事务(如果提供者支持则包括嵌套的事务)。 y 使用Errors集合检查数据源返回的错误。 y 通过Version属性读取所使用的ADO执行版本。 y 使用OpenSchema方法获取数据库纲要信息。 新概念 SQL Server 2005 教程 326 提 示 可以像执行Connection对象的本地方法一样执行命令或存储过程。 例如,使用Connection对象连接一个ODBC数据源的方法如下: Dim cn As Connection cn.Open "PROVIDER=MSDASQL;DSN=book;uid=bookadm;pwd=bookadm" 上面示例中,PROVIDER指的是数据源提供者,DSN为ODBC数据源的名称,uid为登 录账户,pwd为与登录账户对应的密码。 也可以使用其他的OLE DB打开一个连接,例如,要打开一个SQL Server的OLE DB的 数据源,可以使用下面的代码: Dim cn As Connection cn.Open "DRIVER=SQL Server;SERVER=LYR;uid=bookadm;pwd=bookadm" 上面示例中的代码都未指定数据库,连接的都是uid默认的登录数据库。如果要指定连 接的数据库,则可以使用下面的代码: Dim cn As Connection cn.Open "DRIVER=SQL Server;SERVER=LYR;uid=bookadm;pwd=bookadm; DATABASE=bookdb" Connection对象的Open方法就是启动和数据源的连接,一旦建立连接,就可以执行对 数据库的操作了。 要终止一个连接,可以使用Close方法。例如,要终止上面建立的连接,可以使用如下 的代码: cn.Close 2. 使用Recordset对象检索数据 ADO的Recordset对象是一个从数据库查询中返回的结果集。任何时候,Recordset对象 所指的当前记录均为集合内的单个记录。可使用Recordset对象操作来自提供者的数据。使 用ADO时,通过Recordset对象可对几乎所有数据进行操作。 在打开Recordset之前设置CursorType属性来选择游标类型或使用Open方法传递 CursorType参数。在ADO中定义了4种不同的游标类型: y 动态游标 用于查看其他用户所做的添加、更改和删除,并用于不依赖书签的 Recordset中各种类型的移动。如果提供者支持,可使用书签。 y 键集游标 其行为类似动态游标,不同的只是禁止查看其他用户添加的记录,并 禁止访问其他用户删除的记录,其他用户所做的数据更改将依然可见。它始终支 持书签,因此允许Recordset中各种类型的移动。 y 静态游标 提供记录集合的静态副本以查找数据或生成报告。它始终支持书签, 因此允许Recordset中各种类型的移动。其他用户所做的添加、更改或删除将不可 见。 327 第11章 Chapter 11 使用VB开发SQL Server应用程序 y 仅向前游标 除仅允许在记录中向前滚动之外,其行为类似动态游标。这样,当 需要在Recordset中单程移动时,就可提高性能。 提 示 如果没有指定游标类型,ADO将默认打开仅向前游标。 Open方法的语法格式如下: recordset.Open Source, ActiveConnection, CursorType, LockType, Options 其中各参数的含义为: y Source 用于对数据进行检索的SQL语句、表名、存储过程调用或持久Recordset 文件名。 y ActiveConnection 有效的Connection对象变量名或字符串,包含ConnectionString 参数。 y CursorType 确定提供者打开Recordset时应该使用的游标类型。其取值及其含义如 表11.7所示。 y LockType 确定提供者打开Recordset 时应该使用的锁定(并发)类型的 LockTypeEnum值,其值及其含义如表11.8所示。 y Options 用于指示提供者如何计算Source参数,其取值及其含义如表11.9所示。 表11.7 CursorType的取值及其含义 取值 含义 adOpenForwardOnly (默认值)打开仅向前类型游标 adOpenKeyset 打开键集类型游标 adOpenDynamic 打开动态类型游标 adOpenStatic 打开静态类型游标 表11.8 LockType的取值及其含义 取值 含义 adLockReadOnly (默认值)只读——不能改变数据 adLockPessimistic 保守式锁定(逐个)——提供者完成确保成功编辑记录所需的 工作,通常通过在编辑时立即锁定数据源的记录来完成 adLockOptimistic 开放式锁定(逐个)——提供者使用开放式锁定,只在调用 Update 方法时才锁定记录 adLockBatchOptimistic 开放式批更新——用于批更新模式(与立即更新模式相对) 例如,下面的代码首先连接bookdb数据库,然后使用Open方法打开authors表: Dim cn As Connection Set cn = New Connection cn.CursorLocation = adUseClient 新概念 SQL Server 2005 教程 328 cn.Open "PROVIDER=MSDASQL;DSN=book;uid=bookadm;pwd=bookadm" Set rs = New Recordset rs.CursorType = adOpenStatic rs.LockType = adLockOptimistic rs.Open "authors", cnScan, , , adCmdTable 表11.9 Options的取值及其含义 取值 含义 adCmdText 指示提供者应该将 Source 作为命令的文本定义来计算 adCmdTable 指示 ADO 生成 SQL 查询以便从 Source 命名的表返回所有行 adCmdTableDirect 指示提供者更改从 Source 命名的表返回的所有行 adCmdStoredProc 指示提供者应该将 Source 视为存储的过程 adCmdUnknown 指示 Source 参数中的命令类型为未知 adCommandFile 指示应从 Source 命名的文件中恢复持久(保存的)Recordset adExecuteAsync 指示应异步执行 Source adFetchAsync 指示在提取 CacheSize 属性中指定的初始数量后,应该异步提 取所有剩余的行 打开Recordset时,当前记录位于第一个记录(如果有),并且BOF和EOF属性设置为 False。如果没有记录,BOF和EOF属性设置是True。 假设提供者支持相关的功能,可以使用MoveFirst、MoveLast、MoveNext、MovePrevious 和Move方法,以及AbsolutePosition、AbsolutePage和Filter属性来重新确定当前记录的位置。 仅向前Recordset对象只支持MoveNext方法。当使用Move方法访问每个记录(或枚举 Recordset)时,可使用BOF和EOF属性查看是否移动已经超过了Recordset的开始或结尾。 Recordset 对象可支持两类更新:立即更新和批更新。使用立即更新,一旦调用Update 方法,对数据的所有更改将被立即写入现行数据源。也可以将值的数组作为参数传递来使 用AddNew和Update方法,同时更新记录的若干字段。 如果提供者支持批更新,可以使提供者将多个记录的更改存入缓存,然后使用 UpdateBatch 方法在单个调用中将它们传输给数据库。这种情况应用于使用AddNew、 Update和Delete方法所做的更改。调用UpdateBatch方法后,可以使用Status属性检查任何数 据冲突并加以解决。 在结束对打开的Recordset对象的操作后,可使用Close方法释放所有关联的系统资源。 关闭对象并非将它从内存中删除,可以更改它的属性设置并在以后使用Open方法再次将其 打开。要将对象从内存中完全删除,可将对象变量设置为Nothing。 例如,要关闭上面的Recordset对象,可以使用下面的代码: rs.Close 或者 Set rs = Nothing 329 第11章 Chapter 11 使用VB开发SQL Server应用程序 3. 使用Command对象执行SQL语句 使用Command对象查询数据库并返回Recordset对象中的记录,以便执行大量操作或处 理数据库结构。 使用Command对象的集合、方法和属性可以进行下列操作: y 使用CommandText属性定义命令(例如SQL语句)的可执行文本。 y 通过Parameter对象和Parameters集合定义参数化查询或存储过程参数。 y 可使用Execute方法执行命令并在适当的时候返回Recordset对象。 y 执行前应使用CommandType属性指定命令类型以优化性能。 y 使用Prepared属性决定提供者是否在执行前保存准备好(或编译好)的命令版本。 y 使用CommandTimeout属性设置提供者等待命令执行的秒数。 y 通过设置ActiveConnection属性使打开的连接与Command对象关联。 y 设置Name属性将Command标识为与Connection对象关联的方法。 y 将Command对象传输给Recordset的Source属性,以便获取数据。 要执行Command,只需通过它所关联的Connection对象的Name属性,将其简单调用即 可。必须将Command的ActiveConnection属性设置为Connection对象。如果Command带有参 数,则将这些参数的值作为参数传输给方法。 Command对象中,最常用的方法就是Execute方法,用来执行指定的查询、SQL语句、 存储过程或特定提供者的文本等内容。其语法格式如下: 对于不按行返回的命令字符串: connection.Execute CommandText, RecordsAffected, Options 对于按行返回的命令字符串: Set recordset = connection.Execute (CommandText, RecordsAffected, Options) 其中各参数含义为: y CommandText 字符串,包含要执行的SQL语句、表名、存储过程或特定提供者 的文本。 y RecordsAffected 提供者向其返回操作所影响的记录数目。 y Options 指示提供者应如何为CommandText参数赋值,其取值及其含义如表11.10 所示。 表11.10 Options的取值及其含义 取值 含义 adCmdText 指示提供者应将 CommandText 赋值为命令的文本定义 adCmdTable 指示 ADO 应生成 SQL 查询,以便从 CommandText 命名的表中 返回所有行 adCmdTableDirect 指示提供者应从 CommandText 命名的表中返回所有行 adCmdTable 指示提供者应将 CommandText 赋值为表名 新概念 SQL Server 2005 教程 330 (续表) 取值 含义 adCmdStoredProc 指示提供者应将 CommandText 赋值为存储过程 adCmdUnknown 指示 CommandText 参数中的命令类型未知 adExecuteAsync 指示命令应该异步执行 adFetchAsync 指示 CacheSize 属性指定的初始数量之后的行应异步提取 下面是使用Command对象删除表T1的例子: Dim cmd As ADODB.Command Dim SQL_Str As String SQL_Str = "Drop Table T1" cmd.ActiveConnection = cn 'cn为有效的Connection对象 cmd.SQL_Str 如果要向执行的SQL语句传递参数,可以使用CreateParameter方法。其语法格式如下: Set parameter = command.CreateParameter (Name, Type, Direction, Size, Value) 其中各参数含义如下: y Name 代表Parameter对象名称。 y Type 指定Parameter对象数据类型。其设置如表11.11所示。 y Direction 指定Parameter对象类型。其设置如表11.12所示。 y Size 指定参数值最大长度(以字符或字节数为单位)。 y Value 指定Parameter对象值。 表11.11 Type的设置及其含义 设置值 含义 adArray 与其他类型一起加入逻辑 OR,以指示该数据是哪种类型的安全数组 (DBTYPE_ARRAY) adBigInt 8 字节带符号的整数(DBTYPE_I8) adBinary 二进制值(DBTYPE_BYTES) adBoolean 布尔型值(DBTYPE_BOOL) adByRef 与其他类型一起加入逻辑 OR,以指示该数据是其他类型数据的指针 (DBTYPE_BYREF) adBSTR 以空结尾的字符串 (Unicode) (DBTYPE_BSTR) adChar 字符串值(DBTYPE_STR) adCurrency 货币值(DBTYPE_CY)。货币数字的小数点位置固定、小数点右侧有 4 位数字。 该值保存为 8 字节的范围为 10 000 的带符号整型值 adDate 日期值(DBTYPE_DATE)。日期按双精度型数值来保存,数字全部表示从 1899 年 12 月 30 开始的日期数。小数部分是一天当中的片段时间 adDBDate 日期值(yyyymmdd)(DBTYPE_DBDATE) 331 第11章 Chapter 11 使用VB开发SQL Server应用程序 (续表) 设置值 含义 adDBTime 时间值(hhmmss)(DBTYPE_DBTIME) adDBTimeStamp 时间戳(yyyymmddhhmmss 加 10 亿分之一的小数)(DBTYPE_DBTIMESTAMP) adDecimal 具有固定精度和范围的精确数字值(DBTYPE_DECIMAL) adDouble 双精度浮点值(DBTYPE_R8) adEmpty 未指定值(DBTYPE_EMPTY) adError 32 位错误代码(DBTYPE_ERROR) adGUID 全局唯一的标识符(GUID)(DBTYPE_GUID) adIDispatch OLE 对象上 Idispatch 接口的指针(DBTYPE_IDISPATCH) adInteger 4 字节的带符号整型(DBTYPE_I4) adIUnknown OLE 对象上 IUnknown 接口的指针(DBTYPE_IUNKNOWN) adLongVarBinary 长二进制值(仅用于 Parameter 对象) adLongVarChar 长字符串值(仅用于 Parameter 对象) adLongVarWChar 以空结尾的长字符串值(仅用于 Parameter 对象) adNumeric 具有固定精度和范围的精确数字值(DBTYPE_NUMERIC) adSingle 单精度浮点值(DBTYPE_R4) adSmallInt 2 字节带符号整型(DBTYPE_I2) adTinyInt 1 字节带符号整型(DBTYPE_I1) adUnsignedBigInt 8 字节不带符号整型(DBTYPE_UI8) adUnsignedInt 4 字节不带符号整型(DBTYPE_UI4) adUnsignedSmallInt 2 字节不带符号整型(DBTYPE_UI2) adUnsignedTinyInt 1 字节不带符号整型(DBTYPE_UI1) adUserDefined 用户定义的变量(DBTYPE_UDT) adVarBinary 二进制值(仅 Parameter 对象) adVarChar 字符串值(仅 Parameter 对象) adVariant 自动变体型(DBTYPE_VARIANT) adVector 与其他类型一起加入逻辑 OR 中,指示数据是 DBVECTOR 结构(由 OLE DB 定 义)。该结构含有元素的计数和其他类型(DBTYPE_VECTOR)数据的指针 adVarWChar 以空结尾的 Unicode 字符串(仅 Parameter 对象) adWChar 以空结尾的 Unicode 字符串(DBTYPE_WSTR) 表11.12 Direction的设置及其含义 设置值 含义 adParamUnknown 指示参数方向为未知 adParamInput 默认值。指示输入参数 adParamOutput 指示为输出参数 adParamInputOutput 指示为输入参数和输出参数 adParamReturnValue 指示为返回值 例如,下面的代码就是使用Command对象向authors表插入记录: Dim cmd As ADODB.Command 新概念 SQL Server 2005 教程 332 Dim cmd As Command Dim au_id As Integer Dim au_name As String Dim au_address As String Dim au_tel As String '?代表未知的值,可以由CreateParameter方法指定 cmd.CommandText = "INSERT authors VALUES(?,?,?,?)" cmd.CreateParameter , adInteger, adParamInput, 4 cmd.CreateParameter , adChar, adParamInput, 8 cmd.CreateParameter , adChar, adParamInput, 50 cmd.CreateParameter , adChar, adParamInput, 15 'au_id、au_name、au_address和au_tel是包含具体值的变量 '其值可以从其他任何地方获取 cmd.Parameters(0) = au_id cmd.Parameters(1) = au_name cmd.Parameters(2) = au_address cmd.Parameters(3) = au_tel cmd.Execute 4. 使用Command对象执行存储过程 存储过程具有输入参数,也可能具有输出参数。因此,使用Command对象执行存储过 程时,应当指定其输入和输出参数。 下面通过注释说明使用Command对象来执行存储过程的过程: Dim cmd As New ADODB.Command Dim Param0 As New ADODB.Parameter 'Param0将作为输入的Parameter对象 Dim Param1 As New ADODB.Parameter ' Param1将作为输出的Parameter对象 Dim in_value As String Dim out_value As Integer cmd.ActiveConnection = cn 'cn为一个有效的Connection对象 cmd.CommandType = adCmdStoredProc '表明执行的是一个存储过程 cmd.CommandText = "ProcTest" 'ProcTest为要执行的存储过程名 '设置输入的Parameter对象 Param0.Direction = adParamInput '表明该Parameter对象为输入参数 Param0.Type = adChar Param0.Size = 6 '输入参数的长度为6个字符 cmd.Parameters.Append Parm0 '使用Append方法将Param0加入到Parameters集合中 '设置输出的Parameter对象 Param1.Direction = adParamOutput '表明该Parameter对象为输入参数 Param1.Type = adInteger Param1.Size = 4 '输入参数的长度为6个字符 cmd.Parameters.Append Parm1 '使用Append方法将Param0加入到Parameters集合中 Param0.Value = in_value ' in_value是输入参数的变量,例如,其值为“985240” cmd.Execute '执行存储过程 out_value = Param1.value 333 第11章 Chapter 11 使用VB开发SQL Server应用程序 5. 错误处理 任何涉及ADO对象的操作都会生成一个或多个提供者错误。每个错误出现时,一个或 多个Error对象将被放到Connection对象的Errors集合中。当另一个ADO操作产生错误时, Errors集合将被清空,并在其中放入新的Error对象集。 通过Error对象的属性可获得每个错误的详细信息,包括以下内容: y Description属性包含错误的文本。 y Number属性包含错误常量的长整型整数值。 y Source属性标识产生错误的对象。在向数据源发出请求之后,Errors集合中如有多 个Error对象,该属性将十分有用。 y SQLState和NativeError属性提供来自SQL数据源的信息。 例如,可以使用MsgBox函数来提示出现的错误信息: For Each err In cn.Errors MsgBox "Number:" & err.Number & vbCrLf & "Source:" & err.Source & vbCrLf & "Text:" & err.Description Next 提 示 vbCrLf表示回车换行。 6. 程序示例 在上面讲述的内容的基础上,下面编制一个简单的数据库操作程序,其功能是对bookdb 数据库中的authors表进行作者搜索、添加记录、删除记录和浏览记录的功能。 程序的主界面如图11.23所示。 根据“作者ID”文本框的输入值,可以搜索指定的记录,也可以删除记录。即“搜索” 和“删除”两个按钮只使用“作者ID”文本框的值,将忽略其他文本框的值。 “添加”按钮的功能是根据窗口中几个文本框的值来添加一个记录。 “浏览”按钮的功能是对现有的记录进行浏览,单击将打开一个新的对话框,如图11.24 所示。 图 11.23 程序主界面 图 11.24 “浏览作者信息”对话框 新概念 SQL Server 2005 教程 334 主窗体的名称为frmAuthor,Caption属性的值为“作者信息管理”,其中的文本框和按 钮的名称及其属性设置如表11.13所示。 表11.13 主窗体中的文本框和按钮的名称及其属性设置 控件名称及类型 DataField 属性 Caption 属性 txtAuthor_id,文本框 author_id txtAuthor_Name,文本框 author_name txtAddress,文本框 address txtTelephone,文本框 telephone cmdSearch,按钮 搜索 cmdAdd,按钮 添加 cmdDelete,按钮 删除 cmdScan,按钮 浏览 注 意 主窗体和“浏览作者信息”窗体中的Lable控件只设置Caption属性为相应的值即可, 其余属性均保持为默认值。因此,不再在表中列出。 “浏览作者信息”窗体的名称为frmScan,Caption属性的值为“浏览作者信息”,其中 的文本框和按钮的名称及其属性设置如表11.14所示。 表11.14 “浏览作者信息”窗体中的文本框和按钮的名称及其属性设置 控件名称及类型 DataField 属性 Caption 属性 txtScan_Author_id,文本框 author_id txtScan_Author_Name,文本框 author_name txtScan_Address,文本框 address txtScan_Telephone,文本框 telphone cmdFirst,按钮 第一个 cmdPrevious,按钮 上一个 cmdNext,按钮 下一个 cmdLast,按钮 最后一个 主窗体的代码如下: Dim cn As Connection Private Sub cmdAdd_Click() Dim cmd As Command Dim au_id As Integer Dim au_name As String Dim au_address As String Dim au_tel As String 335 第11章 Chapter 11 使用VB开发SQL Server应用程序 Dim err As ADODB.Error Set cmd = New Command au_id = txtAuthor_id.Text au_name = txtAuthor_Name.Text au_address = txtAddress.Text au_tel = txtTelephone.Text With cmd .ActiveConnection = cn .CommandText = "INSERT authors VALUES(?,?,?,?)" .CreateParameter , adInteger, adParamInput, 4 .CreateParameter , adChar, adParamInput, 8 .CreateParameter , adChar, adParamInput, 50 .CreateParameter , adChar, adParamInput, 15 End With cmd.Parameters(0) = au_id cmd.Parameters(1) = au_name cmd.Parameters(2) = au_address cmd.Parameters(3) = au_tel On Error GoTo ErrorHandler cmd.Execute MsgBox "成功插入数据!" ErrorHandler: For Each err In cn.Errors MsgBox "Number:" & err.Number & vbCrLf & "Source:" & err.Source & vbCrLf & "Text:" & err.Description Next End Sub Private Sub cmdDelete_Click() Dim cmd As Command Dim au_id As Integer Dim err As ADODB.Error Set cmd = New Command au_id = txtAuthor_id.Text With cmd .ActiveConnection = cn .CommandText = "DELETE authors WHERE author_id = ?" .CreateParameter , adInteger, adParamInput, 4 End With cmd.Parameters(0) = au_id On Error GoTo ErrorHandler cmd.Execute MsgBox "成功删除数据!" ErrorHandler: For Each err In cn.Errors 新概念 SQL Server 2005 教程 336 MsgBox "Number:" & err.Number & vbCrLf & "Source:" & err.Source & vbCrLf & "Text:" & err.Description Next End Sub Private Sub cmdScan_Click() frmScan.Show End Sub Private Sub cmdSearch_Click() Dim cmd As Command Dim au_id As Integer Dim err As ADODB.Error Set cmd = New Command Set rs = New Recordset au_id = CInt(txtAuthor_id.Text) With cmd .ActiveConnection = cn .CommandText = "SELECT * FROM authors WHERE author_id = ?" .CreateParameter , adInteger, adParamInput, 4 End With cmd.Parameters(0) = au_id Set rs = cmd.Execute '绑定约束控件和数据源 Set txtAuthor_id.DataSource = rs Set txtAuthor_Name.DataSource = rs Set txtAddress.DataSource = rs Set txtTelephone.DataSource = rs End Sub Private Sub Form_Load() Set cn = New Connection cn.CursorLocation = adUseClient cn.Open "PROVIDER=MSDASQL;DSN=book;uid=bookadm;pwd=bookadm" End Sub Private Sub Form_Unload(Cancel As Integer) cn.Close End Sub “浏览作者信息”窗体的代码如下: Dim cnScan As Connection Dim rsScan As Recordset Private Sub cmdFirst_Click() rsScan.MoveFirst End Sub Private Sub cmdLast_Click() rsScan.MoveLast 337 第11章 Chapter 11 使用VB开发SQL Server应用程序 End Sub Private Sub cmdNext_Click() rsScan.MoveNext If rsScan.EOF Then rsScan.MoveLast End Sub Private Sub cmdPrevious_Click() rsScan.MovePrevious If rsScan.BOF Then rsScan.MoveFirst End Sub Private Sub Form_Load() Set cnScan = New Connection cnScan.CursorLocation = adUseClient cnScan.Open "PROVIDER=MSDASQL;DSN=book;uid=bookadm;pwd=bookadm" Set rsScan = New Recordset rsScan.CursorType = adOpenStatic rsScan.LockType = adLockOptimistic rsScan.Open "authors", cnScan, , , adCmdTable '绑定约束控件和数据源 Set txtScan_Author_id.DataSource = rsScan Set txtScan_Author_Name.DataSource = rsScan Set txtScan_Address.DataSource = rsScan Set txtScan_Telephone.DataSource = rsScan End Sub Private Sub Form_Unload(Cancel As Integer) rsScan.Close cnScan.Close End Sub 11.5 课堂演练 本演练建立客户信息管理系统,该管理系统和本章的示例程序类似。主要包括客户添 加、删除、浏览以及搜索功能。因此,其界面设计、代码编写与本章中的程序类似。主要 操作步骤如下: 在Visual Basic中设计界面,其效果如图11.25、图11.26所示。这两张图与图11.23 和图11.24不同的是本例中包含的是客户有关的信息。 新概念 SQL Server 2005 教程 338 图 11.25 客户信息管理主界面 图 11.26 “浏览客户信息”窗口 代码编写和示例基本相同,不同的是本演练是针对clients表进行的。 11.6 小结 数据库应用程序的开发有许多方式,但是由于ODBC API和嵌入式SQL语言比较复杂, 而且其编译过程比较繁琐,故现在最普遍的是使用Visual Basic等集成开发环境,结合ODBC 或者OLE DB技术来开发数据库应用程序。本章正是基于此,主要介绍了ODBC、OLE DB 等技术。还介绍了在Visual Basic开发环境中的ADO数据库编程技术。 ODBC是一项非常重要的技术,它已经成为操纵数据库的标准。程序开发人员只需知 道ODBC的接口,而无需知道具体的数据源是何种类型,就可以进行数据库程序开发。虽 然微软推出的OLE DB技术有取代ODBC的倾向,但是在ODBC广泛普及的现在,其重要性 是不容忽视的。 使用OLE DB不仅可以连接关系型数据库,还可以连接非关系型数据库。它提供了系统 级编程接口,而ADO则是OLE DB界面,提供了对OLE DB的包装,使得使用更加方便。 要使用ADO进行数据库编程,主要是理解其提供的三大对象:Connection、Recordset 和Command对象的使用。三者之间是息息相关、互相牵连的。Command对象必须依赖 Connection对象,而Recordset对象则要视Connection对象与Command对象的状态而定。 11.7 课后练习 11.7.1 简答题 (1)简要叙述ADO中主要的3个对象及其功能。 (2)简要叙述利用ADO对象在程序中操纵数据库的主要步骤。 11.7.2 操作题 利用VB编制一个管理公告信息的程序,具备浏览、添加和删除功能。 第 12 章 开发 Web 数据库 12 Chapter 本章导读: ” ASP工作原理和基础 ” 虚拟目录设置 ” ASP内置对象 ” 使用ASP的ADO对象集成Web数据库 ” ASP.NET基础 ” 使用ASP.NET的ADO.NET对象集成Web数据库 12.1 概述 Active Server Pages(ASP)和ASP.NET是微软推出的一种服务器端命令执行环境,它 可以和HTML页面、脚本(包括JavaScript和VBScript脚本)程序与ActiveX组件建立或者执 行动态的、交互式Web服务器应用程序。而且其提供的ADO组件和ADO.NET组件可以使用 户能很方便地实现Web数据库的集成。 在使用ASP和ASP.NET之前,了解其工作原理是很有必要的。另外,由于ASP和 ASP.NET是在服务器端运行的,因此要正确运行ASP和ASP.NET文件,需要设置虚拟目录。 12.1.1 ASP和ASP.NET简介 ASP和ASP.NET是内嵌在HTML文件中的,与Perl语言或者C语言等建立的传统的公共 网关接口(CGI)应用程序相比,ASP和ASP.NET则显得容易和方便得多。 当浏览器向Web服务器请求ASP或ASP.NET文件时,服务器端脚本便开始运行。Web 服务器调用ASP或ASP.NET来处理所请求的文件,然后生成一个Web页返回浏览器。因为 ASP和ASP.NET脚本是运行在服务器端的,而发送到客户端浏览器的只是一个经过处理后 的Web页(只显示结果),所以,ASP和ASP.NET源代码并不会被看到。这样就可提高其 安全性。 除了普通的脚本任务,也可以使用ASP和ASP.NET将脚本扩展到COM组件,以便于重 复利用已经开发的程序模块,减少开发时间。 使用ASP和ASP.NET进行Web数据库集成的的工作流程如图12.1所示。当客户端请求包 含ASP和ASP.NET文件时,Web服务器将ASP和ASP.NET文件中对数据库的操作通过OLE 新概念 SQL Server 2005 教程 340 DB发送给数据库服务器。在数据库处理完毕后,将结果通过OLE DB传送Web服务器,Web 服务器以HTML的形式生成结果并回传给客户端浏览器。 ASP和ASP.NET最大的优点就是网络流量小,可以很大地减轻网络负担,因为在网络 传输的只是Web服务器返回的检索结果。其另外一个明显的优点就是可以解决浏览器的兼 容性问题,因为脚本是在服务器端运行的,返回的只是一个HTML文件。而对所有的浏览 器都是支持HTML文件的。 图 12.1 ASP 和 ASP.NET 集成 Web 数据库的工作流程 12.1.2 虚拟目录设置 要正确执行ASP和ASP.NET文件,需要将其放在虚拟目录中,然后在浏览器中输入文 件的URL来请求文件。 提 示 ASP和ASP.NET文件必须接受IIS的处理,无法通过输入其物理地址来请求浏览ASP 和ASP.NET文件。另外,本章例子在Windows 2003 Server和IIS 6.0(Internet Information Services,Internet信息服务)上调试通过。 ASP文件可以在下面的环境中运行: y Windows Vista,需要安装Internet信息服务(IIS)。默认情况下Vista不安装IIS,需 要从“打开或关闭Windows功能”对话框中安装IIS 7.0。 y Windows 2000/2003,安装了Internet信息服务,可以安装IIS 4.0/5.0/6.0。 y Windows NT Server 4.0,而且安装了IIS 2.0及其以上版本。 y Windows XP,安装了Personal Web Server(PWS)。 ASP.NET要求除了安装IIS外,还需要安装.NET Framework框架,浏览器要求Internet Explorer 5.5以上版本。.NET Framework框架是.NET的核心,ASP.NET运行时需要.NET Framework框架的支持。ASP.NET开发时可以采用Visual Basic.NET语言,也可以采用Visual Web服务器 ASP脚本和ADO对象 ASP.NET脚本和ADO.NET对象 Internet/ Intranet 客户端浏览器 返回的Web页面 (结果显示) SQL Server 服务器 OLE DB 341 第12章 Chapter 12 开发Web数据库 C#语言。当然,也可以直接安装Visual Studio.NET或者Visual Studio 2005,其中就包含了.NET Framework框架。 下面以Windows 2003 Server上的IIS 6.0为例,介绍一下虚拟目录 的设置,操作步骤如下: 在“控制面板”窗口中,执行“管理工具”|“Internet信息 服务”命令,打开“Internet信息服务”窗口,如图12.2所示。 图 12.2 “Internet 信息服务”窗口 在“默认网站”上右击鼠标,执行“属性”命令,打开“默认网站 属性”对话框, 如图12.3所示。在此对话框中可以设置网站的主目录、IP地址及其端口等属性。设置完成后, 单击“确定”按钮即可。 图 12.3 “默认网站 属性”对话框 设 置 Web 站 点的名称。 该Web站点的 IP地址,一般是本 机的地址。 该选项卡可以设置Web站 点所在的物理目录 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第12章\建立虚拟目 录.avi。 新概念 SQL Server 2005 教程 342 提 示 如果已经设置了Web站点,可以跳过这一步的操作,直接进入下一步。 在“默认网站”上右击鼠标,执行“新建”子菜单中的“虚拟目录”命令,打开 “虚拟目录创建向导”对话框。 单击“下一步”按钮,输入虚拟目录的别名,如图12.4所示。 图 12.4 输入虚拟目录的别名 单击“下一步”按钮,向导提示输入虚拟目录对应的物理目录,如图12.5所示。 图 12.5 输入虚拟目录对应的物理目录 单击“下一步”按钮,出现设置权限对话框,如图12.6所示。 虚拟目录的别名 物理目录 单击可选择 物理目录 343 第12章 Chapter 12 开发Web数据库 图 12.6 设置虚拟目录权限 单击“下一步”按钮,出现“完成”对话框,单击“完成”按钮即可。 提 示 如果要在已经创建的虚拟目录中运行ASP和ASP.NET文件,则可以右击该虚拟目录, 执行“属性”命令,在“虚拟目录”选项卡中的“执行许可”列表框中,选择“纯脚本” 或者“脚本和可执行程序”选项。关于ASP.NET虚拟目录的详细设置可以参考12.3节。 12.2 使用ASP集成Web数据库 ASP使用VBScript语言或者JScript语言作为脚本语言,实际工作中,由于VBScript是 Visual Basic语言的子集,它们共用相同的语法和对象命名约定,因此使用VBScript语言较 多一些。 12.2.1 一个简单的ASP网页 ASP文件均以.asp作为文件后缀,具体的脚本是嵌在<%和%>之间的,在其内部,可以 使用脚本命令来控制数据库的操作及其他操作,在该符号外部,可以使用任何HTML语言 代码。 例如,下面是一个经典的ASP示例程序: 简单的ASP网页 <%@LANGUAGE=VBScript%> <%For i=1 to 7 %> > Hello World!
<%Next%>
一定要设置该项, 否则不能运行ASP 文件 新概念 SQL Server 2005 教程 344 用记事本或者其他编辑软件编辑后,保存到上面所建虚拟目录对应的物理目录中,文 件名为testasp.asp。打开浏览器,在地址栏中输入http://166.111.46.52/test/testasp.asp,按 Enter 键,可看到显示的结果,如图12.7所示。 图 12.7 简单的 ASP 文件 12.2.2 ASP内置对象 ASP内置了6个对象,它们是: y Server对象 该对象提供了服务器端的一个应用工具。 y Request对象 主要用于从客户端取得信息。 y Response对象 主要将信息送给客户端。 y Session对象 存储在一个Session内的用户信息。 y Application对象 在一个ASP应用程序中,让不同的客户端共享信息。 y ObjectContext对象 可以配合Microsoft Transaction Server进行分布式事务处理。 1. Server对象 通过Server对象可以访问服务器上的方法和属性。它具有下述方法和属性: y CreateObject方法 用于创建一个服务器组件的实例。 y HTMLEncode方法 对指定的字符串按照HTML编码。 y MapPath方法 将某虚拟路径转换为物理路径。 y URLEncode方法 将URL编码规则用于字符串,包括转义字符。 y ScriptTimeOut属性 规定一个脚本文件执行的最长时间。 其中最常用的是CreateObject方法,它用来创建一个服务器组件的示例。例如,下面的 代码就是创建ADO的Connection对象的一个实例cnn: Set cnn = Server.CreateObject("ADODB.Connection") 345 第12章 Chapter 12 开发Web数据库 2. Request对象 可以使用Request对象来获取对HTTP请求中传递的任何信息的访问。获取的方法包括 通过POST方法或者GET方法、Cookie以及客户端证书从HTML表单传递的参数。通过 Request对象也可以访问发送到服务器的二进制数据,例如文件上载等。 Request对象包含下述方法和对象集合: y Write方法 直接给浏览器发送信息。 y Redirect方法 将一个用户重定向至另外一个URL。 y ContentType方法 控制发送的内容类型。 y Cookies方法 设置Cookie值。 y Buffer方法 设置缓冲区信息。 y QueryString集合 HTTP查询字符串中的变量值。 y Form集合 HTTP请求中窗体元素的值。 y Cookies集合 HTTP请求中发送的Cookies值。 y ClientCertificate集合 HTTP请求中发送的客户许可证中所存的域值。 y ServerVariables集合 预先设定的服务器的环境变量的值。 例如,可以使用下面的代码来取得请求网页中的文本框等的值: Var1 = Request.Form("Text1") 其中Text1为文本框等的名称。 如果要显示所有的环境变量的值,可使用下面的ASP文件: 显示所有的环境变量 <%@LANGUAGE=VBScript%> <%For each Name in Request.ServerVariables %> <%Next%>
<%=Name%> <%=Request.ServerVariables(Name)%>
将此文件保存为disp_variable.asp,在浏览器的地址栏中输入该文件,按下Enter键,可 看到运行结果,如图12.8所示。 新概念 SQL Server 2005 教程 346 图 12.8 显示服务器端的环境变量 3. Response对象 可以使用Response对象来控制发送给用户的信息。Response具有如下的方法、属性或 者集合: y AddHeader方法 设置HTML头标名的值。 y AppendToLog方法 在Web服务器日志的末尾添加字符串。 y BinaryWrite方法 将给定的信息写入当前的HTTP输出中。 y Clear方法 擦除所有缓存的HTML输出。 y End方法 停止处理ASP文件并返回当前结果。 y Flush方法 将缓存的输出立刻送往浏览器。 y Redirect方法 重定向至另外一个URL。 y Write方法 将一个变量作为字符串送往当前的HTTP输出。 y Buffer属性 表明某页是否已经缓存。 y ContentType属性 指定响应的HTTP内容的类型。 y Expires属性 指定网页在浏览器上告诉缓存中的时限。 y ExpiresAbsolute属性 指定存储于浏览器上某页的终止的日期和时间。 y Status属性 服务器返回的状态行值。 y Cookies集合 指定Cookies值。 例如,可以使用Write方法将某一字符串的值显示在HTTP浏览器上: 简单的ASP网页 <%@LANGUAGE=VBScript%> <% Dim StrTest StrTest = "这是一个字符串!" Response.Write StrTest %> 347 第12章 Chapter 12 开发Web数据库 执行结果是在浏览器中显示“这是一个字符串!”。 4. Session对象 Session对象用来存储特定用户会话所需的信息。当用户在不同Web页之间跳转时,不 会丢失存储在Session对象中的变量。这些变量在用户访问应用程序页的整个期间都会保留。 Session对象具有下述的属性和方法: y Abandon方法 撤销一个Session对象。 y SessionID属性 返回该用户Session的标识符。 y TimeOut属性 应用程序Session状态的时限。 例如,当一个用户登录到某页面后,可以使用Session对象来保留其用户名和密码,便 于后面使用。 5. Application对象 Application对象在特定的用户间共享信息。它具有下述的方法和事件: y Lock方法 锁定数据,防止其他人修改。 y Unlock方法 解锁对数据的锁定,允许其他人修改。 y Application_OnEnd事件 当所有浏览器关闭时触发。 y Application_OnStart事件 当任一浏览器启动时触发。 例如,使用Application对象可以统计访问次数。 6. ObjectContext对象 ObjectContext对象用来提交或者中止由ASP脚本启动的事务。它一般用来说明Microsoft Transaction Server(MTS)对象或者控制数据库事务。 12.2.3 书籍信息查看系统 ASP内置了ADO组件,使用ADO组件就可以进行Web数据库的开 发。关于ADO的详细概念可以参考第11章的介绍。本节将以一个ASP Web数据库程序来介绍使用ASP开发Web数据库应用程序的一般过 程。 使用ASP开发Web数据库应用程序的一般步骤如下: 建立数据库、设置登录账户及其用户,并设置其相应的权限。 设置数据源。比较习惯的是使用ODBC数据源。 编制代码。 在本节的示例中,建立一个查询书籍信息的Web数据库系统,包含两个ASP文件: listbook.asp和listauthor.asp两个文件。listbook.asp文件以分页的方式显示所有书籍的信息, 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第 12 章\ 书籍信息 ASP.avi。 新概念 SQL Server 2005 教程 348 如图12.9所示。 图 12.9 书籍信息界面 提 示 如果用户单击“作者ID”,则显示结果将以作者ID进行排序。同样,单击“书名”、 “价格”和“出版社”,将进行相应的排序。默认情况下,以“书籍ID”进行排序。 如果用户单击书籍对应的“作者ID”,则会显示相应的作者的信息。例如,单击第2 条记录对应的“作者ID”(值为1),则listauthor.asp将会处理“作者ID”为1的作者的记录, 并显示出信息,如图12.10所示。 图 12.10 作者信息界面 listbook.asp文件的代码如下: <%'*****adovbs.inc包含了记录集的当前页、每一页的记录数目等参数的定义%> 349 第12章 Chapter 12 开发Web数据库 书籍信息

书籍信息


<%'********确定当前页 IF Request.QueryString("MOVE")="NEXT" THEN Session("CurrentPage")=Session("CurrentPage")+1 END IF%> <%IF Request.QueryString("MOVE")="PREV" THEN Session("CurrentPage")=Session("CurrentPage")-1 END IF%> <%IF Session("CurrentPage")="" THEN Session("CurrentPage")=1 END IF%> <%'********确定排序方式 IF Request.QueryString("ORDER")="BOOK_NAME" THEN OrderBy="ORDER BY book_name" END IF%> <%IF Request.QueryString("ORDER")="AUTHOR_ID" THEN OrderBy="ORDER BY author_id" END IF%> <%IF Request.QueryString("ORDER")="PRICE" THEN OrderBy="ORDER BY price" END IF%> <%IF Request.QueryString("ORDER")="PUBLISHER" THEN OrderBy="ORDER BY publisher" END IF%> <%IF Request.QueryString("ORDER")="" THEN OrderBy="ORDER BY book_id" END IF%> <%'********连接数据源 Set MyConn=Server.CreateObject("ADODB.Connection") Set RS=Server.CreateObject("ADODB.RecordSet")%> <%'********数据源名称为book,用户名和密码均为bookadm%> <%MyConn.Open "book","bookadm","bookadm"%> <%'********获得书籍信息的记录集 SQLQuery1 = "SELECT * FROM book " SQLQuery = SQLQuery1 + OrderBy RS.Open SQLQuery, MyConn,adOpenStatic%> <%'********确定总的书籍数目%> <%Set RSCount=Server.CreateObject("ADODB.RecordSet") RSCount.Open "SELECT COUNT(*) CountRs FROM book",MyConn%> <%IF RS.BOF and RS.EOF then %> 新概念 SQL Server 2005 教程 350

现在没有书籍!

<%ELSE %> <%'*****设置每一页中的记录数目 RS.PageSize=5 '*******设置当前页 RS.AbsolutePage=Session("CurrentPage") '*******显示当前页的记录%> <%NumRows=0%> <%WHILE NOT RS.EOF AND NumRows <%i=(Session("CurrentPage")-1) * RS.PageSize + NumRows + 1%> <%RS.MoveNext NumRows=NumRows+1 WEND%> 351 第12章 Chapter 12 开发Web数据库
书籍ID 书名 作者ID 价格 出版社
<%=RS("book_id")%> <%=RS("book_name")%> "> <%=RS("author_id")%> <%=RS("price")%> <%=RS("publisher")%>

共有<%=RSCount("CountRs")%>本书籍,这是第 <%=Session("CurrentPage")%>页。

<% IF Session("CurrentPage")>1 THEN %> [上一页] <% END IF %> <% IF Session("CurrentPage") [下一页] <% END IF %>

<%END IF %> <%'**********关闭连接%> <%RS.Close%> <%RSCount.Close%> <%MyConn.Close%> listauthor.asp文件接受传递的author_id的值,并检索相应的作者信息,然后将其显示在 屏幕上,其源代码如下: 作者信息

<%'********获取传递的参数author_id%> <%author_id = Request.QueryString("author_id")%> <%'********连接数据源 Set MyConn=Server.CreateObject("ADODB.Connection") Set RS=Server.CreateObject("ADODB.RecordSet") MyConn.Open "book","bookadm","bookadm"%> <%'********获得作者信息的记录集 SQLQuery = "SELECT * FROM authors WHERE author_id = " + author_id RS.Open SQLQuery, MyConn,adOpenStatic%> <%'********显示作者信息%> 作者信息


作者ID:<%=author_id%>

作者姓名:<%=RS("author_name")%>

地址:<%=RS("address")%>

电话:<%=RS("telphone")%>

<%'********关闭连接 RS.Close MyConn.Close%> 新概念 SQL Server 2005 教程 352 提 示 <%=RS("author_name")%>是用来显示作者的姓名的,使用<% Response. Write RS("author_name")%>也可以完成同样的功能。 12.3 使用ASP.NET集成Web数据库 本节介绍ASP.NET的虚拟目录的设置,然后介绍ASP.NET连接数据库的核心组件 ADO.NET。在此基础上,给出一个基于ASP.NET的书籍信息查看系统。 注 意 由于篇幅有限,本书不详细介绍ASP.NET的具体实用,仅就数据库连接方面做一简 单介绍。要获得ASP.NET的详细内容,请查阅相关书籍。 12.3.1 ASP.NET的虚拟目录设置 要运行ASP.NET,必须对虚拟目录进行设置。操作步骤如下: 在“控制面板”窗口中,执行“管理工具”|“Internet信息服务管理器”命令,打 开“Internet信息服务”窗口。 选择“Web服务扩展”选项,打开Web服务扩展选项设置界面,如图12.11所示。 如果ASP.NET v2.0.50727处于禁止状态,则单击“允许”按钮启动ASP.NET。 图 12.11 “Web 服务扩展”选项设置 在左侧窗口的“默认网站”上右击鼠标,执行“属性”命令,打开“默认网站 属 性”对话框。 打开ASP.NET选项卡,在“ASP.NET版本”下拉列表框中选择2.050727,即设置 ASP.NET支持ASP.NET 2.0,如图12.12所示。 353 第12章 Chapter 12 开发Web数据库 图 12.12 设置 ASP.NET 的版本 设置完成后,单击“确定”按钮。 12.3.2 ADO.NET连接数据库 ADO.NET提供了4种数据提供程序,如表12.1所示。 表12.1 ASP.NET的4种数据提供程序 数据提供程序 访问的数据库类型 SQL Server.NET 用于访问 SQL Server 2000 及以上版本的数据库 OLE DB.NET 用于访问 SQL Server 7.0 及以下版本和其他类型的数据库 OracleDB.NET 用于访问 Oracle 8i、Oracle 9i 及以上版本的数据库 ODBC.NET 用于访问 ODBC 数据源 下面对表12.1中的数据提供程序进行简单介绍。 y SQL Server.NET数据提供程序 该数据提供程序包含的核心对象为SqlConnet- ction、SqlCommand、SqlDataReader和SqlDataAdapter,使用这4个对象时需要引用 命名空间System.Data.SqlClient。这种数据提供程序主要用来操作SQL Server 2000 或SQL Server 2005版本。 y OLE DB.NET数据提供程序 包含的核心对象为OLEDbConnection、OLEDbComm- and、OLEDbDataReader和OLEDbDataAdapter,这4个对象包含在System.Data. OLEDB命名空间中。主要用访问Access、FoxPro等简单的数据库。 y OracleD.NET数据提供程序 包含的核心对象为OracleConnection、OracleComm- and、OracleDataReader和OracleDataAdapter,这4个对象包含在 System.Data.Oracle- Client命名空间中,主要支持 Oracle 8.1及以上版本。 y ODBC.NET数据提供程序 包含的核心对象为OdbcConnection、OedbcCommand、 OdbcDataReader和OdbcDataAdapter,这4个对象包含在System.Data.Odbc命名空间 新概念 SQL Server 2005 教程 354 中,通过ODBC建立的数据源都可以通过该数据提供程序进行访问。 组成.NET数据提供程序的4个核心对象如表12.2所示。 表12.2 .NET数据提供程序的核心对象 对象 属性 Connection 用于建立与特定数据源的连接 Command 用于对数据源执行命令,公开 Parameters,并且可以从 Connection 在 Transaction 的范围内执行 DataRerder 用于从数据源中读取数据记录 DataAdapter 用数据源填充 DataSet 对象并进行更新,DataAdapte 是数据提供程序与 DataSet 的 接口 ADO.NET有两个核心组件,.NET数据提供程序和数据集DataSet。.NET数据提供程序 是数据库的访问接口,负责建立连接和数据的操作,它作为DataSet对象与数据源之间的桥 梁,负责将数据源中的数据取出后置入DataSet对象中或将数据存回数据源。DataSet包含一 个或多个数据表(DataTable)。通过两个核心组件访问数据库的方法有以下两种: y 使用Connection对象、Command对象和DataReader对象实现数据访问。 y 使用DataAdapter对象和DataSet对象实现数据访问。 12.3.3 基于ASP.NET的书籍信息查看系统 下面采用ASP.NET重新编写一下前面的书籍信息查看系统。本 信息系统采用C#语言编写,在显示书籍信息时,采用的是GridView 控件来绑定数据源进行显示;在显示作者的详细信息时,采用的是 DetailView控件来绑定数据源进行显示。 书籍信息查看系统的用户界面如图12.13所示;单击“作者ID” 后显示作者信息的界面如图12.14所示。 图 12.13 书籍信息显示界面(ASP.NET) 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第 12 章 \ 书籍信息 ASP.NET.avi。 355 第12章 Chapter 12 开发Web数据库 图 12.14 作者信息查看(ASP.NET) 该书籍查询系统共包含4个文件:BookList.aspx、BookList.aspx.cs、AuthorView.aspx和 AuthorView.aspx.cs。 BookList.aspx文件用于显示书籍信息,代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="BookList.aspx.cs" Inherits="BookList" %> 书籍管理
书籍信息
新概念 SQL Server 2005 教程 356
BookList.aspx.cs是BookList.aspx中处理数据的类定义等,代码如下: using System; using System.Data.SqlClient ; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class BookList : System.Web.UI.Page { public string DBConnString; protected void Page_Load(object sender, EventArgs e) { //连接数据库命令字符串 DBConnString = "Data Source=localhost;Initial Catalog=bookdb;User ID=sa; Password=sa"; //连接数据库 SqlConnection con = new SqlConnection(DBConnString); con.Open(); // 连接指定表 SqlDataAdapter Myadapter = new SqlDataAdapter("Select * From book", con); DataSet ds = new DataSet(); // 填充数据 Myadapter.Fill(ds, "bookinfo"); //数据源设置 GridViewBook.DataSource = ds.Tables["bookinfo"].DefaultView; // 数据成员 GridViewBook.DataMember = "bookinfo"; //数据绑定 GridViewBook.DataBind(); if (ds.Tables[0].Rows.Count > 0) { //设置显示位置、列宽度和数据显示位置 357 第12章 Chapter 12 开发Web数据库 GridViewBook.HeaderRow.HorizontalAlign = HorizontalAlign.Center; GridViewBook.Columns[0].ItemStyle.Width = 80; GridViewBook.Columns[1].ItemStyle.Width = 300; GridViewBook.Columns[2].ItemStyle.Width = 80; GridViewBook.Columns[3].ItemStyle.Width = 50; GridViewBook.Columns[4].ItemStyle.Width = 100; GridViewBook.Columns[0].ItemStyle.HorizontalAlign = HorizontalAlign.Center; GridViewBook.Columns[1].ItemStyle.HorizontalAlign = HorizontalAlign.Left; GridViewBook.Columns[2].ItemStyle.HorizontalAlign = HorizontalAlign.Center; GridViewBook.Columns[3].ItemStyle.HorizontalAlign = HorizontalAlign.Center; GridViewBook.Columns[4].ItemStyle.HorizontalAlign = HorizontalAlign.Left; } } } AuthorView.aspx用于接收传递来的作者ID,以显示作者信息,代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="AuthorView.aspx.cs" Inherits="AuthorView" %> 作者信息
作者信息

新概念 SQL Server 2005 教程 358
AuthorView.aspx.cs用于处理AuthorView.aspx文件中的数据,代码如下: using System; using System.Data.SqlClient ; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class AuthorView : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string DBConnString; string SqlString; string qsfrom; qsfrom = Request.QueryString["authorid"]; DBConnString = "Data Source=localhost;Initial Catalog=bookdb;User ID=sa; Password=sa"; SqlString = "Select * From authors Where author_id='" + qsfrom + "'"; //Response.Write(SqlString); //连接数据库 SqlConnection con = new SqlConnection(DBConnString); con.Open(); // 连接指定表 SqlDataAdapter Myadapter = new SqlDataAdapter(SqlString, con); DataSet ds = new DataSet(); Myadapter.Fill(ds,SqlString); //装入数据 DetailsViewAtuthor.DataSource = ds.Tables[0].DefaultView; //数据源设置 DetailsViewAtuthor.DataMember = SqlString; //数据成员 DetailsViewAtuthor.DataBind(); } protected void BtnClose_Click(object sender, EventArgs e) { //关闭窗口 Response.Write(""); } } 359 第12章 Chapter 12 开发Web数据库 12.4 课堂演练 利用第3章创建的boarddb数据库,对其中的board表进行操作, 编制一个的公告浏览和添加系统,其中公告信息放置在board表中。 操作步骤如下: 首先要设置ODBC数据源,名称设置为board。详细操作步 骤可以参考第11章。 程序结构设计。程序框图如图12.15所示。 图 12.15 公告浏览和添加系统框图 y ListBoard.asp文件,用于显示公告界面如图12.16所示。 图 12.16 显示公告界面 y InputInfo.asp文件,用于输入公告的有关信息,界面如图12.17所示。 y CreateBoard.asp文件,用于将公告信息存入数据库中。 主界面(ListBoard.asp) 显示所有公告 添加公告(CreateBoard.asp) 将用户输入的公告内容添加到 boarddb数据库的board表中 输入公告内容 (InputInfo.asp) 实讲实训 多媒体演示 多媒体演示参见配 套光盘中的\\视频\ 第12章\公告浏览和 发布.avi。 新概念 SQL Server 2005 教程 360 图 12.17 公告的输入界面 12.5 小结 随着ASP的出现,Web服务器上脚本处理使得生成动态Web页面成为可能。ASP文件是 在客户端浏览器发出请求时才生成HTML代码,并返回给客户端。本章介绍了ASP的基础 知识,并以一个示例程序介绍了如何使用ADO连接数据库,并处理返回数据的过程。 实际上,ASP中的ADO对象的使用和Visual Basic中的使用基本上是一致的。因此,如 果熟悉Visual Basic中数据库的操作,则ASP就显得非常简单了。 12.6 课后练习 12.6.1 简答题 (1)简单叙述IIS中虚拟目录的设置过程。 (2)简单叙述ASP对数据库的操作步骤。 12.6.2 操作题 (1)完善本章中书籍信息查询Web数据库系统,加入添加和删除书籍信息的模块。 (2)完善12.4节中的例子,加入用户验证功能。即只有合法用户才能发布公告,用户 名和密码保存在boarddb数据库的users表中。 附录 A SQL 语法符号的表示方法 Transact-SQL语句的语法规则如表A.1所示。 表A.1 SQL语句的语法规则 规则 含义 大写 Transact-SQL 关键字 小写正体 Transact-SQL 语法中用户提供的参数 | (竖线) 分隔括号或大括号内的语法项目。只能选择一个项目 [ ] (方括号) 可选语法项目。不必输入方括号 {}(大括号) 必选语法项。不要输入大括号 [ ,…n ] 表示前面的项可重复 n 次。每一项由逗号分隔 […n ] 表示前面的项可重复 n 次。每一项由空格分隔 加粗 数据库名、表名、列名、索引名、存储过程、实用工具、数据类型名以及必须按所显 示的原样输入的文本 <标签> ::= 语法块的名称。此规则用于对可在语句中的多个位置使用的过长语法或语法单元部分 进行分组和标记。适合使用语法块的每个位置由括在尖括号内的标签表示:<标签> 例如,下面是CREATE DATABASE语句的语法: CREATE DATABASE database_name [ ON [ < filespec > [ ,...n ] ] [ , < filegroup > [ ,...n ] ] ] [ LOG ON { < filespec > [ ,...n ] } ] [ COLLATE collation_name ] [ FOR LOAD | FOR ATTACH ] < filespec > ::= [ PRIMARY ] ( [ NAME = logical_file_name , ] FILENAME = 'os_file_name' [ , SIZE = size ] [ , MAXSIZE = { max_size | UNLIMITED } ] [ , FILEGROWTH = growth_increment ] ) [ ,...n ] < filegroup > ::= FILEGROUP filegroup_name < filespec > [ ,...n ] 其中: CREATE DATABASE和ON等就是Transact-SQL的关键字。 database_name和collation_name等就是需要用户提供的参数。 [FOR LOAD | FOR ATTACH]表示可用FOR LOAD或FOR ATTACH,但是不可同时使 用。 新概念 SQL Server 2005 教程 362 [FOR LOAD | FOR ATTACH]的中括号表示可以使用该项,也可以不使用该项。 ON关键字后面的< filespec >和< filegroup >都表示需要另外说明的,而后面的< filespec > ::=和< filegroup > ::=就是对该项的具体说明。 [,…n]表示,… 附录 B SQL 语法补充 B.1 CREATE DATABASE语法 在第3章介绍了使用企业管理器创建数据库的方法,使用SQL语句同样也可创建数据 库。创建数据库可以使用CREATE DATABASE语句。其完整语法为: CREATE DATABASE database_name [ON [< filespec > [ ,...n ] ] [, < filegroup > [ ,...n ] ] ] [LOG ON { < filespec > [ ,...n ] } ] [COLLATE collation_name ] [FOR LOAD | FOR ATTACH ] < filespec > ::= [ PRIMARY ] ( [ NAME = logical_file_name , ] FILENAME = 'os_file_name' [ , SIZE = size ] [ , MAXSIZE = { max_size | UNLIMITED } ] [ , FILEGROWTH = growth_increment ] ) [ ,...n ] < filegroup > ::= FILEGROUP filegroup_name < filespec > [ ,...n ] 其中各参数具体含义如下: y database_name 新数据库的名称。数据库名称在服务器中必须唯一,并且符合标 识符的规则。database_name最多可以包含128个字符,除非没有为日志指定逻辑名。 如果没有指定日志文件的逻辑名,则SQL Server会通过向database_name追加后缀来 生成逻辑名。该操作要求database_name在123个字符之内,以便生成的日志文件逻 辑名少于128个字符。 y ON 指定显式定义用来存储数据库数据部分的磁盘文件(数据文件)。该关键字 后跟以逗号分隔的项列表,该项用以定义主文件组的数据文件。主文件 组的文件列表后可跟以逗号分隔的项列表(可选),该项用以定义用户 文件组及其文件。 y n 占位符,表示可以为新数据库指定多个文件。 y LOG ON 指定显式定义用来存储数据库日志的磁盘文件(日志文件)。该关键字 后跟以逗号分隔的项列表,项用以定义日志文件。如果没有指 定LOG ON,将自动创建一个日志文件。该文件使用系统生成的名称,大小为数据 库中所有数据文件总大小的25%。 y FOR LOAD 支持该子句是为了与早期版本的SQL Server兼容。数据库在打开dbo 新概念 SQL Server 2005 教程 364 use only数据库选项的情况下创建,并且将其状态设置为正在装载。SQL Server 7.0 版中不需要该子句,因为RESTORE语句可以作为还原操作的一部分重新创建数据 库。 y FOR ATTACH 指定从现有的一组操作系统文件中附加数据库。必须有指定第一 个主文件的 条目。至于其他 条目,只需要与第一次创建数 据库或上一次附加数据库时路径不同的文件的那些条目。必须为这些文件指定 条目。附加的数据库必须使用与SQL Server相同的代码页和排序次序创 建。应使用sp_attach_db系统存储过程,而不要直接使用CREATE DATABASE FOR ATTACH。只有必须指定16个以上的 项目时,才需要使用CREATE DATABASE FOR ATTACH。 提 示 如果将数据库附加到的服务器不是该数据库从中分离的服务器,并且启用了分离的 数据库以进行复制,则应该运行sp_removedbreplication从数据库删除复制。 y collation_name 指定数据库的默认排序规则。排序规则名称既可以是 Windows 排序规则名称,也可以是 SQL 排序规则名称。如果没有指定排序规则,则将 SQL Server 实例的默认排序规则指派为数据库的排序规则。 y PRIMARY 指定关联的列表定义主文件。主文件组包含所有数据库系统 表。还包含所有未指派给用户文件组的对象。主文件组的第一个条目成 为主文件,该文件包含数据库的逻辑起点及其系统表。一个数据库只能有一个主 文件。如果没有指定PRIMARY,那么CREATE DATABASE语句中列出的第一个 文件将成为主文件。 y NAME 为由 定义的文件指定逻辑名称。如果指定了FOR ATTACH, 则不需要指定NAME参数。 y logical_file_name 用来在创建数据库后执行的Transact-SQL语句中引用文件的名 称。logical_file_name 在数据库中必须唯一,并且符合标识符的规则。该名称可以 是字符或 Unicode 常量,也可以是常规标识符或定界标识符。 y FILENAME 为 定义的文件指定操作系统文件名。 y 'os_file_name' 操作系统创建定义的物理文件时使用的路径名和文件 名。os_file_name中的路径必须指定SQL Server实例上的目录。os_file_name不能指 定压缩文件系统中的目录。 提 示 如果文件在原始分区上创建,则os_file_name必须只指定现有原始分区的驱动器字 母。每个原始分区上只能创建一个文件。原始分区上的文件不会自动增长,因此, os_file_name指定原始分区时,不需要指定MAXSIZE和FILEGROWTH参数。 y SIZE 指定中定义的文件的大小。如果主文件的中没有提供 SIZE 参数,那么SQL Server将使用model数据库中的主文件大小。如果次要文件或 365 附录B Appendix B SQL语法补充 日志文件的中没有指定SIZE参数,则SQL Server将使文件大小为1MB。 y size 中定义的文件的初始大小。可以使用千字节(KB)、兆字节(MB)、 千兆字节(GB)或兆兆字节(TB)后缀。默认值为MB。指定一个整数,不要包 含小数位。size 的最小值为512 KB。如果没有指定size,则默认值为1MB。为主文 件指定的大小至少应与model数据库的主文件大小相同。 y MAXSIZE 指定中定义的文件可以增长到的最大大小。 y max_size 中定义的文件可以增长到的最大大小。可以使用千字节 (KB)、兆字节(MB)、千兆字节(GB)或兆兆字节(TB)后缀。默认值为 MB。指定一个整数,不要包含小数位。如果没有指定max_size,那么文件将增长 到磁盘变满为止。 使用一条CREATE DATABASE语句即可创建数据库以及存储该数据库的文件。SQL Server分两步实现CREATE DATABASE语句: (1)SQL Server使用model数据库的副本初始化数据库及其元数据。 (2)然后,SQL Server使用空页填充数据库的剩余部分,除了包含记录数据库中空间 使用情况以外的内部数据页。 B.2 CREATE TABLE语法 CREATE TABLE语法格式如下: CREATE TABLE [ database_name.[ owner ] .| owner.] table_name ( { < column_definition > | column_name AS computed_column_expression | < table_constraint > ::= [ CONSTRAINT constraint_name ] } | [ { PRIMARY KEY | UNIQUE } [ ,...n ] ) [ ON { filegroup | DEFAULT } ] [ TEXTIMAGE_ON { filegroup | DEFAULT } ] < column_definition > ::= { column_name data_type } [ COLLATE < collation_name > ] [ [ DEFAULT constant_expression ] | [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ] ] [ ROWGUIDCOL] [ < column_constraint > ] [ ...n ] < column_constraint > ::= [ CONSTRAINT constraint_name ] { [ NULL | NOT NULL ] | [ { PRIMARY KEY | UNIQUE } [ CLUSTERED | NONCLUSTERED ] [ WITH FILLFACTOR = fillfactor ] [ON {filegroup | DEFAULT} ] ] ] 新概念 SQL Server 2005 教程 366 | [ [ FOREIGN KEY ] REFERENCES ref_table [ ( ref_column ) ] [ ON DELETE { CASCADE | NO ACTION } ] [ ON UPDATE { CASCADE | NO ACTION } ] [ NOT FOR REPLICATION ] ] | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) } < table_constraint > ::= [ CONSTRAINT constraint_name ] { [ { PRIMARY KEY | UNIQUE } [ CLUSTERED | NONCLUSTERED ] { ( column [ ASC | DESC ] [ ,...n ] ) } [ WITH FILLFACTOR = fillfactor ] [ ON { filegroup | DEFAULT } ] ] | FOREIGN KEY [ ( column [ ,...n ] ) ] REFERENCES ref_table [ ( ref_column [ ,...n ] ) ] [ ON DELETE { CASCADE | NO ACTION } ] [ ON UPDATE { CASCADE | NO ACTION } ] [ NOT FOR REPLICATION ] | CHECK [ NOT FOR REPLICATION ] ( search_conditions ) } 其中各参数含义如下: y database_name.[ owner ] .| owner.] table_name 表的完整名称。 y column_name 是表中的列名。以timestamp 数据类型创建的列可以省略 column_name。如果不指定column_name,timestamp列的名称默认为timestamp。 y computed_column_expression 是定义计算列值的表达式。计算列是物理上并不存 储在表中的虚拟列。计算列由同一表中的其他列通过表达式计算得到。例如,计 算列可以这样定义:cost AS price * qty。表达式可以是非计算列的列名、常量、函 数、变量,也可以是用一个或多个运算符连接的上述元素的任意组合。表达式不 能为子查询。 y ON {filegroup | DEFAULT} 指定存储表的文件组。如果指定filegroup,则表将存 储在指定的文件组中。数据库中必须存在该文件组。如果指定DEFAULT,或者根 本未指定ON参数,则表存储在默认文件组中。 y TEXTIMAGE_ON 是表示text、ntext和image列存储在指定文件组中的关键字。如 果表中没有text、ntext或image列,则不能使用TEXTIMAGE ON。如果没有指定 TEXTIMAGE_ON,则text、ntext和image列将与表存储在同一文件组中。 y data_type 指定列的数据类型。可以是系统数据类型或用户定义数据类型。用户 定义数据类型必须先用sp_addtype创建,然后才能在表定义中使用。 y DEFAULT 如果在插入过程中未显式提供值,则指定为列提供的值。DEFAULT 定义可适用于除定义为timestamp或带IDENTITY属性的列以外的任何列。 y constant_expression 是用作列的默认值的常量、NULL或系统函数。 367 附录B Appendix B SQL语法补充 y IDENTITY 表示新列是标识列。当向表中添加新行时,SQL Server将为该标识列 提供一个唯一的、递增的值。标识列通常与PRIMARY KEY约束一起用作表的唯一 行标识符。可以将IDENTITY属性指派给tinyint、smallint、int、bigint、decimal(p,0) 或numeric(p,0)列。对于每个表只能创建一个标识列。不能对标识列使用绑定默认 值和DEFAULT约束。必须同时指定种子和增量,或者二者都不指定。如果二者都 未指定,则取默认值(1,1)。 y seed 是装入表的第一行所使用的值。 y increment 是添加到前一行的标识值的增量值。 y NOT FOR REPLICATION 表示当复制登录(如sqlrepl)向表中插入数据时,不强制 IDENTITY属性。复制的行必须保留发布数据库中所赋予的键值;NOT FOR REPLICATION子句确保不向复制进程所插入的行赋予新的标识值。其他登录所插入 的行仍然具有以通常的方式创建的新标识值。建议同时使用具有NOT FOR REPLICATION的CHECK约束,以确保赋予的标识值处于当前数据库所需的范围内。 y ROWGUIDCOL 表示新列是行的全局唯一标识符列。对于每个表只能指派一个 uniqueidentifier 列作为ROWGUIDCOL 列。ROWGUIDCOL 属性只能指派给 uniqueidentifier列。如果数据库兼容级别小于或等于65,则ROWGUIDCOL关键字无效。 y collation_name 指定列的排序规则。排序规则名称既可以是Windows排序规则名 称,也可以是SQL排序规则名称。collation_name仅适用于数据类型为char、varchar、 text、nchar、nvarchar及ntext的列。如果没有指定该参数,那么如果列的数据类型 是用户定义的,则该列的排序规则就是用户定义数据类型的排序规则,否则就是 数据库的默认排序规则。 y CONSTRAINT 是可选关键字,表示PRIMARY KEY、NOT NULL、UNIQUE、 FOREIGN KEY或CHECK约束定义的开始。约束是特殊属性,用于强制数据完整 性并可以为表及其列创建索引。constrain_name是约束的名称。 y NULL | NOT NULL 是确定列中是否允许空值的关键字。 y PRIMARY KEY 是通过唯一索引对给定的一列或多列强制实体完整性的约束。对 于每个表只能创建一个PRIMARY KEY约束。 y UNIQUE 是通过唯一索引为给定的一列或多列提供实体完整性的约束。一个表可 以有多个 UNIQUE 约束。 y CLUSTERED|NONCLUSTERED 是表示为PRIMARY KEY或UNIQUE约束创建 聚集或非聚集索引的关键字。PRIMARY KEY约束默认为CLUSTERED,UNIQUE 约束默认为NONCLUSTERED。 y [ WITH FILLFACTOR = fillfactor ] 指定SQL Server存储索引数据时每个索引页 的充满程度。用户指定的fillfactor取值范围从1到100。如果没有指定fillfactor,则 默认为0。创建索引时,fillfactor的值越低,不必分配新空间即可由新索引项使用 的空间就越多。 y FOREIGN KEY…REFERENCES 是为列中的数据提供引用完整性的约束。 FOREIGN KEY约束要求列中的每个值在被引用表中对应的被引用列中都存在。 FOREIGN KEY约束只能引用被引用表中为 PRIMARY KEY或UNIQUE约束的列 新概念 SQL Server 2005 教程 368 或被引用表中在UNIQUE INDEX内引用的列。 y ref_table 是FOREIGN KEY约束所引用的表名。 y (ref_column[,…n]) 是FOREIGN KEY约束所引用的表中的一列或多列。 y ON DELETE {CASCADE | NO ACTION} 指定当要创建的表中的行具有引用关 系,并且从父表中删除该行所引用的行时,要对该行采取的操作。默认设置为 NOACTION。如果指定CASCADE,则从父表中删除被引用行时,也将从引用表 中删除引用行。如果指定NO ACTION,SQL Server将产生一个错误并回滚父表中 的行删除操作 y ON UPDATE {CASCADE | NO ACTION} 指定当要创建的表中的行具有引用关 系,并且在父表中更新该行所引用的行时,要对该行采取的操作。默认设置为NO ACTION。如果指定CASCADE,则在父表中更新被引用行时,也将在引用表中更 新引用行。如果指定NO ACTION,SQL Server将产生一个错误并回滚父表中的行 更新操作。 y CHECK 是通过限制可输入到一列或多列中的可能值强制域完整性的约束。 y NOT FOR REPLICATION 是用于防止在复制所使用的分发过程中强制CHECK 约束的关键字。当表是复制发布的订户时,不要直接更新订阅表,而要更新发布 表,然后让复制进程将数据分发回订阅表。可以在订阅表上定义CHECK约束,以 防用户修改订阅表。但是如果不使用NOT FOR REPLICATION子句,CHECK约束 同样会防止复制进程将修改从发布表分发给订阅表。NOT FOR REPLICATION子 句表示对用户的修改(而不是对复制进程)强加约束。NOT FOR REPLICATION CHECK约束适用于被更新记录的前像和后像,以防在复制范围中添加记录或从复 制范围中删除记录。将检查所有删除和插入操作。如果操作在复制范围内,则拒 绝执行该操作。 y logical_expression 是返回TRUE或FALSE的逻辑表达式。 y column 是用括号括起来的一列或多列,在表约束中表示这些列用在约束定义中。 y [ASC | DESC] 指定加入到表约束中的一列或多列的排序次序。默认设置为 ASC。 B.3 账户管理 在第4章介绍了使用企业管理器来添加、删除、查看登录账户的操作过程。在SQL Server 中,还提供了几个存储过程用于对账户进行操作。 B.3.1 添加登录账户 添加登录账户可以使用sp_addloin存储过程,其语法格式如下: sp_addlogin [ @loginame = ] 'login' [ , [ @passwd = ] 'password' ] [ , [ @defdb = ] 'database' ] [ , [ @deflanguage = ] 'language' ] [ , [ @sid = ] sid ] 369 附录B Appendix B SQL语法补充 [ , [ @encryptopt = ] 'encryption_option' ] 其中各参数含义如下: y [@loginame =] 'login' 登录的名称。login的数据类型为sysname,没有默认设置。 y [@passwd =] 'password' 登录密码。password的数据类型为sysname,默认设置为 NULL。sp_addlogin执行后,password被加密并存储在系统表中。 y [@defdb =] 'database' 登录的默认数据库(登录后登录所连接到的数据库)。 database 的数据类型为sysname,默认设置为master。 y [@deflanguage =] 'language' 用户登录到SQL Server时系统指派的默认语言。 language的数据类型为sysname,默认设置为NULL。如果没有指定language,那么 language被设置为服务器当前的默认语言(由sp_configure配置变量default language 定义)。更改服务器的默认语言不会更改现有登录的默认语言。language保持与添 加登录时所使用的默认语言相同。 y [@sid =] sid 安全标识号(SID)。sid的数据类型为varbinary(16),默认设置为NULL。 如果sid为NULL,则系统为新登录生成SID。尽 管 使 用 varbinary数据类型,非NULL 的值也必须正好为16个字节长度,且不能事先存在。SID很有用,例如,如果要编 写 SQL Server 登录脚本,或要将 SQL Server 登录从一台服务器移动到另一台, 并且希望登录在服务器间具有相同的 SID 时。 y [@encryptopt =] 'encryption_option' 指定当密码存储在系统表中时,密码是否要加 密。encryption_option的数据类型为varchar(20)。其取值如表B.1所示。 表B.1 encryption_option的取值及其含义 取值 含义 NULL 加密密码。这是默认设置 skip_encryption 密码已加密。SQL Server 应该存储值而且不用重新对其加密 skip_encryption_old 已提供的密码由 SQL Server 较早版本加密。SQL Server 应该存储值而且不用重 新对其加密。此选项只供升级使用 其余几个与登录账户有关的存储过程如表B.2所示。 表B.2 用于对登录账户进行操作的存储过程 存储过程 功能 sp_helplogins 查看登录账户 sp_droplogin 删除登录账户 sp_password 改变登录账户的密码 B.3.2 添加用户账户 要添加用户账户,可以使用sp_adduser存储过程。其语法格式如下: sp_adduser [ @loginame = ] 'login' [ , [ @name_in_db = ] 'user' ] [ , [ @grpname = ] 'group' ] 新概念 SQL Server 2005 教程 370 其中各参数含义如下: y [@loginame =] 'login' 用户的登录名称。login的数据类型是sysname,没有默认值。 login必须是现有SQL Server登录或Windows用户。 y [@name_in_db =] 'user' 新用户的名称。user的数据类型为sysname,其默认值为 NULL。如果没有指定user,则用户的名称默认为login名称。指定user即为新用户 在数据库中给予一个不同于SQL Server上的登录ID的名称。 y [@grpname =] 'group' 组或角色,新用户自动地成为其成员。group的数据类型为 sysname,默认值为NULL。group必须是当前数据库中有效的组或角色。 提 示 要查看用户,可以使用sp_helpuser存储过程。 B.3.3 与角色有关的存储过程 使用sp_addrole存储过程可以为当前数据库创建新的角色。其语法格式为: sp_addrole [ @rolename = ] 'role' [ , [ @ownername = ] 'owner' ] 其中各参数含义为: y [@rolename =] 'role' 新角色的名称。role的数据类型为sysname,没有默认值。role 必须是有效标识符,并且不能已经存在于当前数据库中。 y [@ownername =] 'owner' 新角色的所有者,owner的数据类型为sysname,默认值 为dbo。owner必须是当前数据库中的某个用户或角色。当指定Windows用户时,需 要指定该Windows用户在数据库中可被识别的名称(用 sp_grantdbaccess添加)。 提 示 要查看角色,可以使用sp_helprole存储过程。 使用sp_addrolemember存储过程可以将成员(用户或者另外一个角色)加入到数据库 角色中。其语法格式如下: sp_addrolemember [ @rolename = ] 'role' , [ @membername = ] 'security_account' 其中各参数含义如下: y [@rolename =] 'role' 当前数据库中SQL Server角色的名称。role的数据类型为 sysname,没有默认值。 y [@membername =] 'security_account' 添加到角色的安全账户。security_account的 数据类型为sysname,没有默认值。security_account可以是所有有效的SQL Server 用户、SQL Server角色或是所有已授权访问当前数据库的Windows用户或组。当添 加Windows用户或组时,需要指定在数据库中用来识别该Windows用户或组的名称 (可以使用sp_grantdbaccess添加)。 附录 C SQL Server 的内置函数 Transact-SQL编程语言提供了3种类型的函数。它们分别是: y 行集合(Rowset)函数 用做类似参照表一类的函数。 y 聚集(Aggregate)函数 对一个集合值进行操作,但是只返回单个数值。 y 标量(Scalar)函数 标量函数只对单个数值操作,并且返回单个值。无论表达式 是否有效,标量函数都可以使用。标量函数又可以分为10类,如表C.1所示。 表C.1 标量函数分类 标量函数分类 说明 配置函数 返回有关当前配置的信息 游标函数 返回有关游标的信息 日期时间函数 对输入的日期和时间数值进行操作,并且返回字符串、数字或者日期时间值 数学函数 对输入的数值进行计算,并返回一个数字数值 数据元函数 返回数据库和数据对象的信息 安全函数 返回用户和角色的信息 字符串函数 对字符串(char 或 varchar)进行操作,并返回一个字符串或者数字数值 系统函数 对 SQL Server 服务器和数据库对象进行操作,并返回服务器配置和数据库对象数 值等信息 系统统计函数 返回系统的统计信息 文本和图像函数 对文本或图像数值或列进行操作,并返回这些数值的有关信息 C.1 行集合函数 在Transact-SQL语句中,行集合函数是类似参照表一类的函数。行集合函数返回一个 对象,返回的对象可以像表一样被Transact-SQL语句所参照。行集合函数包括: CONTAINSTABLE FREETEXTTABLE OPENDATASOURCE OPENQUERY OPENROWSET OPENXML 注 意 行集合函数为不确定性函数,即返回值是不确定的,它们对同一个输入值执行操作 后,每次返回的数值不一定相同。 新概念 SQL Server 2005 教程 372 C.1.1 CONTAINSTABLE函数 CONTAINSTABLE函数对表中所有的列或指定列做全文查询,其返回值为零个、一个 或多个这些列的数据行。查询的时候可以精确查询或者模糊查询。 使用CONTAINSTABLE的查询又称为包含式全文查询。CONTAINSTABLE函数的语法 格式为: CONTAINSTABLE ( table , { column | * } , ' < contains_search_condition > ' [ , top_n_by_rank ] ) < contains_search_condition > ::= { < simple_term > | < prefix_term > | < generation_term > | < proximity_term > | < weighted_term > } | { ( < contains_search_condition > ) { AND | AND NOT | OR } < contains_search_condition > [ ...n ] } < simple_term > ::= word | " phrase " < prefix term> ::= < generation_term > ::= FORMSOF ( INFLECTIONAL , < simple_term > [ ,...n ] ) < proximity_term > ::= { < simple_term > | < prefix_term > } { { NEAR | ~ } { < simple_term > | < prefix_term > } } [ ...n ] < weighted_term > ::= ISABOUT ( { { | < prefix_term > | < generation_term > | < proximity_term > } [ WEIGHT ( weight_value ) ] } [ ,…n ] ) 其中各参数含义如下: y table参数指出做全文检索的表的名称。table参数中不能指定一个服务器的名称. y column参数说明要查询的列。如果使用*,则说明对表table中所有的列进行搜索。 y top_n_by_rank参数说明只返回按降序排列的前n行。n行的取值只能为整数。 y contains_search_condition 说明CONTAINSTABLE 函数的搜索条件。其中 simple_term参数说明了CONTAINSTABLE函数所搜索的单字或短语。如果为短语 时,需要用双引号做定界符。 y prefix_term参数说明了CONTAINSTABLE函数所搜索的字或短语的前缀,需要用 373 附录C Appendix C Server的内置函数 双引号定界。 y generation_term参数说明搜索包含原字的派生字的数据行,其中派生字可以是原字 的名词单数、复数、动词的各个时态等。 y proximity_term参数说明匹配的单字或短语必须互相接近,和AND操作符有些相 似。 y weighted_term参数说明匹配行(查询的结果)和字或短语的列表相匹配,可以随 意给出一个权重数值。 C.1.2 FREETEXTTABLE函数 FREETEXTTABLE函数可以在一个表的所有列或指定列中搜索一个字符串类型的值, 返回值为与该字符串类型的值相匹配的数据行。 提 示 返回的数据行可以为空、一行或者多行。 使用FREETEXTTABLE的查询又称为自由式全文查询。FREETEXTTABLE函数的语法 格式为: FREETEXTTABLE ( table , { column | * } , 'freetext_string' [ , top_n_by_rank ] ) 其中各参数含义如下: y table参数 说明被查询的表的名称。 y column参数 说明要查询的列,如果使用参数*,说明对表中所有的列都查询。 y freetest_string参数 说明要搜索的字符串。 y top_n_by_rank参数 说明只返回前n行,n的取值只能为整数。 C.1.3 OPENDATASOURCE函数 OPENDATASOURCE函数提供了连接到服务器的功能。语法格式为: OPENDATASOURCE ( provider_name, init_string ) 其中各参数含义如下: y provider_name注册为用于访问数据源的OLE DB提供程序的PROGID的名称,OLE DB提供者用来访问数据源。 y init_string参数是连接字符串,传递给IdataInitialize接口。 C.1.4 OPENQUERY函数 OPENQUERY函数在给定的链接服务器(一个OLE DB数据源)上执行指定的直接传递 查询。可以在查询的FROM子句中像引用表名那样引用OPENQUERY函数。依据OLE DB提 供程序的能力,还可以将OPENQUERY函数引用为INSERT、UPDATE或DELETE语句的目 标表。尽管查询可能返回多个结果集,但是OPENQUERY只返回第一个。 新概念 SQL Server 2005 教程 374 OPENQUERY的语法格式为: OPENQUERY ( linked_server , 'query' ) 其中linked_server为连接服务器的名称。query为在链接的服务器中执行的查询字符串。 C.1.5 OPENROWSET函数 该函数包含访问OLE DB数据源中的远程数据所需的全部连接信息。当访问链接服务器 中的表时,这种方法是一种替代方法,并且是一种使用OLE DB连接并访问远程数据的一次 性的、特殊的方法。可以在查询的FROM子句中像引用表名那样引用OPENROWSET函数。 依据OLE DB提供程序的能力,还可以将OPENROWSET函数引用为INSERT、UPDATE或 DELETE语句的目标表。尽管查询可能返回多个结果集,然而OPENROWSET只返回第一个。 OPENROWSET函数的语法格式为: OPENROWSET ( 'provider_name' , { 'datasource' ; 'user_id' ; 'password' | 'provider_string' } , { [ catalog.] [ schema.] object | 'query' } ) 其中各参数含义如下: y provider_name参数说明OLE DB的提供者名称。 y datasource参数说明OLE DB数据源。该参数包含数据库文件的名称、数据库服务器 的名称或者数据库提供者的名称。 y user_id参数说明连接OLE DB的用户名。 y password参数说明user_id用户的口令。 y provider_string参数是提供者指定的连接字符串。该字符串通过DBPROP_INIT_ PROVIDERSTRING属性初始化OLE DB提供者。 y catalog参数说明所检索的对象所属的目录或者数据库名称。 y schema参数说明所检索的对象的所有者名称。 y object参数说明所检索的对象名称。 y query参数是发送的由OLE DB提供者执行的查询担任字符串。 C.1.6 OPENXML函数 OPENXML函数通过XML文档提供了一个行集视图。由于OPENXML是一个行集提供 者,所以OPENXML可以在Transact-SQL语句中作为一个表或者视图。 OPENXML的语法格式为: OPENXML(idoc int [in],rowpattern nvarchar[in],[flags byte[in]]) [WITH (SchemaDeclaration | TableName)] 其中各参数含义如下: y idoc参数 是XML文档的内部表达式的文档句柄。XML文档的内部表达式可以通 375 附录C Appendix C Server的内置函数 过sp_xml_preparedocument存储过程来创建。 y rowpattern参数 是用来确定结点的Xpath模式。 y flags参数 说明XML数据和关系行集间的映射,以及溢出列如何填充。Flags是一 个可选参数,其取值如表C.2所示。 表C.2 flags参数的取值 取值 说明 0 缺省的属性中心映射 1 使用属性中心映射可以和 XML_ELEMENTS 组合,这样属性中心映射先应用,然后再 对其他没有处理的列应用单元中心映射 2 使用单元中心映射可以和 XML_ATTRIBUTES 组合,这样属性中心映射先应用,然后 再对其他没有处理的列应用单元中心映射 8 可以和 XML_ATTRIBUTES 或者 XML_ELEMENTS 组合 y SchemaDeclaration是窗体的架构定义,其格式如下: ColName ColType [ColPattern | MetaProperty][, ColName ColType [ColPattern | MetaProperty]...] 其中,ColName是行集的列名,ColType是ColName列的数据类型。ColPattern是一个可 选顶,说明XLM结点如何映射到列。MetaPropetry是由OPENXML提供的数据元属性,如果 数据元属性确定,那么该列就包含数据元属性提供的信息。 y TableName参数 是可以给出的表的名称。 C.2 聚集函数 聚集函数对集合中的数值进行计算,并返回单个计算结果。聚集函数通常和SELECT 语句中的GROUP BY子句一起使用。 C.2.1 AVG和SUM函数 AVG计算表达式中各项的平均值,其语法格式如下: AVG ( [ ALL | DISTINCT ] expression ) 其中ALL表示对所有值求平均,DISTINCT排除表达式中的重复值项,expression为确 数字或近似数字数据类型类别的表达式(bit数据类型除外)。 SUM计算表达式中所有值项的和,它忽略NULL值项。其语法格式为: SUM([ALL | DISTINCT] expression ) 其中各参数含义与AVG函数的参数含义相同。 新概念 SQL Server 2005 教程 376 注 意 AVG和SUM忽略NULL值项,而且缺省值为ALL。 C.2.2 MAX和MIN函数 MAX函数返回表达式中的最大值项。其语法格式为: MAX([ALL | DISTINCT] expression ) ALL表示在所有值中取最大值项,DISTINCT排除表达式中的重复值项。expression为 常量、列名、函数以及算术运算符、按位运算符和字符串运算符的任意组合。MAX可用于 数字列、字符列和datetime列,但不能用于bit列。不允许使用聚合函数和子查询。 MIN函数返回表达式中的最小值项。其语法格式为: MIN([ALL | DISTINCT] expression ) 各参数含义同上。 注 意 MAT和MIN忽略NULL值项,而且缺省值为ALL。 C.2.3 COUNT和COUNT_BIG函数 COUNT函数返回一个集合中的项数,返回值为整型。其语法格式为: COUNT({[ALL | DISTINCT] expression }|*)) 其中ALL表示计算除了NULL值项之外的所有其他项,包括重复值项。DISTINCT排除 表达式中的重复值项以及NULL项。 expression表达式可以是除uniqueidentifier、text、image和ntext之外的其他数据类型。如 果表达式为*,就不能带有DISTINCT参数。 COUNT_BIG函数和COUNT函数的功能和用法相同,唯一不同的就是COUNT_BIG返 回值为长整型。 C.2.4 CHECKSUM和CHECKSUM_AGG函数 CHECKSUM函数返回在表的行上或在表达式列表上计算的校验值。CHECKSUM 用于 生成哈希索引。其语法格式为: CHECKSUM ( * | expression [ ,...n ] ) 其中*表示对表中所有的列进行计算。expression为除非可比数据类型之外的任何类型 的表达式。非可比的数据类型包括text、ntext、image、cursor以及sql_variant。 CHECKSUM_AGG函数返回一个集合的校验和。其语法格式为: CHECKSUM_AGG([ALL | DISTINCT] expression ) 其中ALL表示包含所有项,DISTINCT排除表达式中的重复值项。expression表达式为 整型数据类型。 377 附录C Appendix C Server的内置函数 注 意 CHECKSUM_AGG忽略NULL值,而且缺省时默认为ALL。 C.2.5 STDEV、STDEVP、VAR和VARP函数 STDEV返回表达式中所有数值的统计标准偏差。其语法格式为: STDEV(expression) 其中expression表达式为精确数值型或近似数值型数据类型,但是不能为bit数据类型, 返回值为float型。 STDEVP返回表达式中所有数值的填充统计标准偏差。其语法格式为: STDEVP(expression) 其中expression表达式为精确数值型或近似数值型数据类型,但是不能为bit数据类型, 返回值为float型。 VAR返回表达式中所有数值的统计方差。其语法格式为: VAR(espression) 其中espression表达式为精确数值型或近似数值型数据类型,但是不能为bit数据类型, 返回值为float型。 VARP返回表达式中所有数值的填充统计方差。其语法格式为: VARP(espression) 其中espression表达式为精确数值型或近似数值型数据类型,但是不能为bit数据类型, 返回值为float型。 C.2.6 GROUPING函数 GROUPING产生一个附加的列,当用CUBE或ROLLUP运算符添加行时,附加的列输 出值为1,当所添加的行不是由CUBE或ROLLUP产生时,附加列值为0。 GROUPING函数只能和带有CUBE或ROLLUP运算符的GROUP BY子句相关联。 GROUPING函数的语法格式为: GROUPING(column_name) 其中column_name是GROUP BY子句中用于检查CUBE或ROLLUP空值的列。 C.3 配置函数 配置函数返回当前系统的配置信息,如表C.3所示 新概念 SQL Server 2005 教程 378 表C.3 配置函数 函数 说明 @@DATEFIRST 返回 SET DATAFIRST 参数的当前值;SET DATAFIRST 指定每周的第 一天,返回值为短整型;如果值为 1,说明每周第一天为星期一;如果 值为 2,说明每周的一天为星期二;缺省时默认为 7,也就是每周周日 为该星期的第一天 @@DBTS 返回当前数据库的当前 timestamp 数据类型的数值;返回值为一个二进 制型 @@LANGID 返回本地当前使用的语言标识符;返回值为微整型 @@LANGUAGE 返回当前使用的语言名称;返回值为 nvarchar 类型 @@LOCK_TIMEOUT 返回当前的锁定超时设置,单位为毫秒(ms);返回值为整型 @@MAX_CONNECTIONS 返回 SQL Server 允许的同时连接的最大用户数目;返回值为整型 @@MAX_PRECISION 返回当前服务器设置的 decimal 和 numeric 数据类型使用精度;返回值 为短整型 @@NESTLEVEL 返回当前存储过程的嵌套层数;返回值为整型 @@OPTIONS 返回当前 SET 选项的信息;返回值为整型 @@REMSERVER 返回注册记录中显示的远程数据服务器的名称;返回值为 nvarchar(256) 类型 @@SERVERNAME 返回运行 SQL Server 的本地服务器名称;返回值为 nvarchar 类型 @@SERVICENAME 返回 SQL Server 运行时的注册键名称;返回值为 nvarchar 类型 @@SPID 返回服务器处理标识符;返回值为短整型 @@TEXSIZE 返回当前 TEXTSIZE 选项的设置值,返回值为整型;该数值指定了 SELECT 语句返回的 text 和 image 类型数据的最大长度 @@VERSION 返回当前 SQL Server 服务器的日期,版本和处理器类型;返回值为 nvarchar 类型 注 意 所有配置函数都是不确定性函数。也就是说,每次调用的时候,返回数值不一定相 同。另外,配置函数都是以全局变量的形式给出。 C.4 游标函数 游标函数返回当前游标的信息。所有游标函数都不具有确定性。每次用一组特定输入 值调用它们时,返回的结果不总是相同的。 C.4.1 @@CURSOR_ROWS函数 @@CURSOR_ROWS返回连接上最后打开的游标中当前存在的合格行的数量。游标中 379 附录C Appendix C Server的内置函数 的行数返回值及其说明如表C.4所示 表C.4 @@CURSOR_ROWS的返回值 返回值 说明 -m 游标采用异步方式填充;数值 m 为当前键集中的行数 -1 游标为动态游标;动态游标的行数是动态变化的,所以无法确定 0 指定的游标未打开,或者所打开的游标已经关闭或释放 n 游标完全填充;返回值 n 为游标中的行数 C.4.2 CURSOR_STATUS函数 CURSOR_STATUS函数返回游标的当前状态。存储过程调用者通过读取游标的当前状 态,可以判断怎样处理存储过程所返回的结果集合。 CURSOR_STATUS函数的语法格式为: CURSOR_STATUS ( { 'local' , 'cursor_name' } | { 'global' , 'cursor_name' } | { 'variable' , 'cursor_variable' } ) 其中各参数含义如下: y local参数 说明游标为局部游标,cursor_name给出游标的名称。 y global参数 说明游标为全局游标,cursor_name给出游标的名称。 y variable参数 说明游标为局部游标,而且是一变量,同时由cursor_variable给出游 标的变量名称。 CURSOR_STATUS函数的返回类型为smallint数据类型,返回值如表C.5所示。 表C.5 @@CURSOR_STATUS的返回值 返回值 游标名称 游标变量 1 对不敏感游标和键集游标,结果集 合中至少有 1 行数据;对于动态游 标,结果集合中可能有 0、1 和多行 数据 分配给该变量的游标打开,而且对不敏感游标和键集 游标,结果集合中至少有 1 行数据;对于动态游标, 结果集合中可能有 0、1 或多行数据 0 游标的结果集合为空 分配给该变量的游标打开,而且游标的结果集合为空 -1 游标关闭 指派给变量的游标关闭 -2 游标不可用 可能原因是: ① 对 OUTPUT 变量没有指定游标 ② 对 OUTPUT 变量指定了游标,但是游标处于关闭 状态 ③ 没有将游标指派给已声明的游标变量 -3 指定名称的游标不存在 指定名称的游标不存在,或者即使该名称的游标存在, 但是没有分配 新概念 SQL Server 2005 教程 380 C.4.3 @@FETCH_STATUS函数 返回被FETCH语句执行的最后游标的状态,而不是任何当前被连接打开的游标的状 态。 返回值为integer数据类型,返回值如表C.6所示。 表C.6 @@FETCH_STATUS返回值 返回值 说明 0 FETCH 语句执行成功 -1 FETCH 语句执行失败,或者该行超出了结果集合 -2 要提取的行不存在 注 意 由于@@FETCH_STATUS对于在一个连接上的所有游标是全局性的,要小心使用 @@FETCH_STATUS。在执行一条FETCH语句后,必须在对另一游标执行另一FETCH 语 句前测试@@FETCH_STATUS。在任何提取操作出现在此连接上前,@FETCH_STATUS 的值没有定义。 C.5 日期时间函数 日期时间函数用于处理输入的日期和时间数值,并返回一个字符串、数字或者日期时 间数值。SQL Server 2005提供的日期时间函数如表C.7所示。 表C.7 日期时间函数 函数 说明 DATEDD(datepart,number,date) 返回 datetime 类型数值,其值为 date 值加上 datepart 和 number 参数指定的时间间隔 DATEDIFF(datepart,startdate,enddate) 返回 startdate 和 enddate 间的时间间隔,其单位由 datepart 参数 决定 DATENAME(datepart,date) 返回 date 参数对应的字符串,其格式由 datepart 确定 DATEPART(datepart,date) 返回 date 参数对应的整数值,其格式由 datepart 确定 DAY(date) 返回 date 参数的日数,返回值数据类型为 int GETDATE() 按照 SQL Server 规定的格式返回系统当前的日期和时间 GETUTCDATE() 返回 datetime 类型数值,其值表示当前的 UTC 时间(格林威治 时间) MONTH(date) 返回 date 参数的月份,返回值数据类型为 int YEAR(date) 返回 date 参数的年份,返回值数据类型为 int 在日期时间函数中,datepart参数指定了时间的单位。SQL Server 2005中,datepart的取 381 附录C Appendix C Server的内置函数 值如表C.8所示。 表C.8 datepart取值 Datepart 取值 缩写 Year yy, yyyy quarter qq, q Month mm, m dayofyear dy, y Day dd, d Week wk, ww Hour hh minute mi, n second ss, s millisecond Ms C.6 数学函数 数学函数对数字表达式进行数学运算并返回运算结果。数学函数可对SQL Server系统 提供的数字数据(decimal、integer、float、real、money、smallmoney、smallint和tinyint) 进行处理。默认情况下,对float数据类型数据的内置运算的精度为6个小数位。 默认情况下,传递到数学函数的数字将被解释为decimal数据类型。可用CAST或 CONVERT函数将数据类型更改为其他数据类型,例如float类型。 SQL Server 2005提供的数学函数如表C.9所示。 表C.9 数学函数 Datepart 取值 说明 ABS(numeric_expression) 求 numeric_expression 表达式的绝对值 ACOS(float_expression) 求 float_expression 表达式的反余弦 ASIN(float_expression) 求 float_expression 表达式的反正弦 ATAN(float_expression) 求 float_expression 表达式的反正切 ATN2(float_expression1,float_expression2) 求 float_expression1/float_expression2 的反正切 CEILING(numeric_expression) 求大于等于 numeric_expression 表达式的最小整数 COS(float_expression) 求 float_expression 表达式的余弦 COT(float_expression) 求 float_expression 表达式的余切 DEGREES(numeric_expression) 将弧度 numeric_expression 转换为度 EXP(float_expression) 求 float_expression 表达式的指数 FLOOR(numeric_expression) 求小于等于 float_expression 表达式的最大整数 新概念 SQL Server 2005 教程 382 (续表) Datepart 取值 说明 LOG(float_expression) 求 float_expression 表达式的自然对数 LOG10(float_expression) 求 float_expression 表达式以 10 为底的对数 PI() 表示 π,值为 3.141 592 653 589 79 POWER(numeric_expression,y) 求 numeric_expression 的 y 次方 RADIANS(numeric_expression) 将度 numeric_expression 转换为弧度 RAND([seed]) 返回 0 到 1 之间的随机浮点数,可以用整数 seed 来指定 初值 ROUND(numeric_expression,length[,function]) 求表达式 numeric_expression 的四舍五入值和截断值, 四舍五入或截断后保留的位数由 length 指定;function 参数说明 ROUND 函数执行的操作,数据类型必须是 tinyint、smallint 或 int;当 fnuction 的数值为 0 或缺省时, 执行四舍五入操作;否则执行截断操作 SIGN(numeric_expression) 求表达式 numeric_expression 的符号值 SIN(float_expression) 求表达式 float_expression 的正弦 SQUARE(float_expression) 求表达式 float_expression 的平方 SQRT(float_expression) 求表达式 float_expression 的平方根 TAN(float_expression) 求表达式 float_expression 的正切 注 意 像ABS、CEILING、DEGRESS、FLOOR、POWER、RADIANS和SIGN函数,返回 值的数据类型和输入值的数据类型相同。而三角函数和其他函数,包括EXP、LOG、LOG10、 SQUARE和SQRT,将输入值的数据类型转换成float类型,并且返回值为float类型。 当数学函数的float或real结果太小而无法显示时,将发生浮点下溢错误。返回的结果为 0.0,而且不显示错误信息。例如,2的-1000.0次幂数学计算将得到结果0.0。 若向数学函数提供的值不是有效值,将发生域错误。例如,为ASIN函数指定的值必须 在-1.00~1.00之间。如果指定的范围为-2,将发生域错误。 若指定的值超出了允许值,则发生范围错误。例如,POWER(10.0, 400)超出了float数 据类型的最大范围2e+308,而POWER(-10.0,401)超出了float数据类型的最小范围-2e+308。 C.7 元数据函数 元数据函数返回数据库和数据库对象的信息。SQL Server 2005提供的元数据函数如表 C.10所示。 383 附录C Appendix C Server的内置函数 表C.10 元数据函数 函数 说明 COL_LENGTH('table','column') 返回表 table 中的 column 字段的定义长度 COL_NAME(table_id,column_id) 返回与表标识号 table_id和字段标识号 column_id 相对应的列名 COLUMNPROPERTY(id,column,property) 返回字段或者存储过程中某一参数的信息,id 为 表或者存储过程的标识符 DATABASEPROPERTY(database,property) 返回指定的数据库 database 的 preperty 属性值(参 看 DATABASEPROPERTYEX 函数) DATABASEPROPERTYEX(database,property) 返回指定的数据库 database 的 property 属性的当 前值 DB_ID(['database_name']) 返回数据库的标识号;返回值类型为 smallint DB_NAME(database_id) 返回数据库的名称;返回值类型为 nvarchar(128) FILE_ID('file_name') 返回指定的逻辑文件的文件标识号;返回值类型 为 smallint FILE_NAME(file_id) 返回与文件标识号逻辑文件名;返回值类型为 nvarchar(128) FILEGROUP_ID('filegroup_name') 返回指定文件组的文件组标识号;返回值类型为 smallint FILEGROUP_NAME(filegroup_id) 返回与文件组标识号文件组名称;返回值类型为 nvarchar(128) FILEGROUPPROPERTY(filegroup_name,property) 返回数据库文件组 filegroup_name 的 property 属 性值 FILEPROPERTY(filename,property) 返回数据库文件 filename 的 property 属性值 FULLTEXTCATALOGPROPERTY(catalog_name, property) 返回全文目录属性信息 FULLTEXTSERVICEPROPERTY(property) 返回全文服务级属性信息 fn_listextendedproperty ({ default | [ @name = ] 'property_name' | NULL }, { default | [ @level0type = ] level0_object_type' | NULL }, { default | [ @level0name = ] 'level0_object_name' | NULL }, { default | [ @level1type = ] 'level1_object_type' | NULL }, { default | [ @level1name = ] 'level1_object_name' | NULL }, { default | [ @level2type = ] 'level2_object_type' | NULL }, { default | [ @level2name = ] 'level2_object_name' | NULL } ) 返回数据库对象的扩展属性,其中property_name 为属性名,level0_object_type的有效值可以为 USER、TYPE、DEFAULT或NULL,level0_object_ name的有效值可以为DEFAULT、NULL或对象名 称,level1_object_type的有效值可以为TABLE、 VIEW、PROCEDURE、FUNCTION、DEFAULT、 RULE、DEFAULT或NULL,level1_object_name 的有效值可以为DEFAULT、NULL或对象名称, level2_object_type的有效值可以为COLUMN、 PARAMETER 、 INDEX 、 CONSTRAINT 、 TRIGGER、DEFAULT、DEFAULT或NULL, level2_object_name的有效值可以为DEFAULT、 NULL或对象名称;返回值为一个表,该表由 objtype、objname、name和value 4列组成 新概念 SQL Server 2005 教程 384 (续表) 函数 说明 INDEX_COL('table,index_id,key_id) 返回指定索引的字段名,其中 table 为指定的表, index_id 为指定的索引标识符,key_id 为指定的 关键字标识符;返回值类型为 nvarchar(256) INDEXKEY_PROPERTY(table_ID,index_ID,key_ID, property) 返回索引键的信息,其中 table_ID、index_ID 分 别是表、索引和关键字标识符;property 为属性 名,property 的取值可以为:ColumnId,说明索 引在 key_ID 位置的列标识符,或 IsDescending, 说明索引列是如何排序的,如果值为 1,说明为 降序排列,为 0,说明为升序排列 INDEXPROPERTY(table_ID,index,property) 返回 table_ID、index 和 property 参数指定的索引 和属性信息 OBJECT_ID('object') 返回数据对象的标识号;返回值类型为 int OBJECT_NAME(object_id) 返回数据对象名称;返回值类型为 nchar OBJECTPROPERTY(id,property) 返回当前数据库中数据对象的属性信息 @@PROCID 返回当前的存储过程标识符;返回值为整型 SQL_VARIANT_PROPERTY(expression,property) 返回 sql_variant 值的基本数据类型和属性信息 TYPEPROPERTY(type,property) 返回数据类型的属性信息 注 意 DATABASEPROPERTYEX函数是SQL Server 2000版本中的新增函数,DATABASEP- ROPERTY函数和DATABASEPROPERTYEX函数功能基本相同,从而提供了向前兼容性。 C.8 安全函数 安全函数返回有关用户和角色的信息。SQL Server 2005提供的安全函数如表C.11所示。 表C.11 安全函数 函数 说明 FN_TRACE_GETEVENTINFL([ @trace_id=]trace_id) 返回跟踪事件的信息,其中trace_id为int型数据,且不能缺省;返回 值为一个表,该表由两个int型的列组成,列的名称为eventid和 columnid;evernid为跟踪事件的标识符,columnid为每个事件所有字 段的标识符数目 FN_TRACE_GETFILTERINFO([ @traceid=]trace_id) 返回跟踪中使用的过滤器信息,其中trace_id为int型数据,且不能省 略;返回值为一个表,该表由columnid、logical_operator、compar- ison_operator和value四个字段组成,其中columnid、logical_operator、 comparison_operator三个字段为int型,value字段为sql_variant型; columnid为过滤器所应用的字段标识符,logical_operator说明了是否 使用了AND或OR操作符,comparison_operator说明了使用的比较符 (=、<>、<、>、<=、>=、LIKE或NOT LIKE),value指出了对过滤器 所应用的值 385 附录C Appendix C Server的内置函数 (续表) 函数 说明 FN_TRACE_GETINFO([@tracei d=]trace_id) 返回有关跟踪的信息,其中trace_id为整数;如果需要返回所有跟踪 的信息,需要指定trace_id的值为'default';返回值为一个表,该表由 traceid、property和value三个字段组成,其中traceid和property为int 型,value为sq_variant型;traceid为跟踪标识符,property为跟踪的属 性,value为跟踪的属性信息 FN_TRACE_GETTABLE([@file name=]filename,[@numfiles]=]nu mber_files 返回跟踪文件的信息,其中filename为跟踪文件名,number_files为 要读取的翻转文件的数目;可以指定默认值'default'来读取跟踪中的 所有翻转文件;返回值为一个表 HAS_DBACCESS('database_ name') 判断当前用户能否访问database_name参数指定的数据库;返回值可 以是以下3种:1表示当前用户可以访问该数据库;0表示当前用户无 权访问该数据库;NULL表示该数据库不存在 IS_MEMBER({'group'|'role'}) 判断当前用户是否为指定的Windows NT组或SQL Server角色成员; 返回值可以为以下3种:1表示当前用户是指定的Windows NT组或 SQL Server角色成员;0表示当前用户不是指定的Windows NT组或 SQL Server角色成员;NULL表示指定的Windows NT组或SQL Server 角色成员不存在 IS_SRVROLEMEMBER('role' [,'login']) 判断当前用户的登录标识或参数login指定的登录标识是否为参数 role所指定的服务器角色成员;其中参数role的取值可以为sysadmin、 dbcreator、diskadmin、processadmin、serveradmin、setupadmin和 security_admin;返回值可以为以下3种:1表示指定的登录标识是role 角色成员;0表示指定的登录标识不是role角色成员;NULL表示参 数role或login无效 SUSER_SID(['login']) 返回与参数login指定的用户登录标识相对应的登录标识号;返回值 类型为varbinary(85) SUSER_SNAME([server_ user_id]) 返回与参数server_user_id指定的登录标识号相对应的登录标识名 称;返回值类型为nvarchar(256) USER_ID(['user']) 返回user用户或当前用户对应的数据库用户标识号;返回值类型为 smallint USER() 返回当前用户的数据库用户名称;返回值类型为char C.9 字符串函数 字符串函数实现对字符串的操作和运算。除CHARINDEX和PATINDEX外的所有其他 内置字符串函数都具有确定性。每次用一组给定的输入值调用它们时,都返回相同的值。 SQL Server 2005提供的字符串函数如表C.12所示。 新概念 SQL Server 2005 教程 386 表C.12 字符串函数 函数 说明 ASCII(character_ expression) 将字符串表达式character_expression中最左边一个字符转换为ASCII码;返回 值类型为int CHAR(integer_ expression) 将一个整数所代表的ASCII码转换为字符;返回值类型为char(1);对于控制字 符可以使用CHAR函数输入,例如,CHAR(9)表示制表符,CHAR(10)表示换 行符,CHAR(13)表示回车符 CHARINDEX(character_ expression1,character_ex pression2[start_location]) 返回指定的表达式character_expression1在表达式expression2中的开始位置;其 中参数start_location指出在表达式character_expression2中开始搜索的起始位 置,如果start_location 的值为0 、-1 或者缺省,搜索则从表达式 character_expression2的起始位置开始;返回值类型为int DIFFERENCE(character _expression1,character_ Expression2) 比较两个字符串表达式的差异,返回值为0~4 LEFT(character_expres- sion,integer_expression) 返回字符串表达式character_expression中左边integer_expression个字符;返回 值类型为varchar LEN(string_expression) 返回字符串的长度,不包括字符串尾部的空格;返回值类型为int LOWER(character_ expression) 将字符串表达式character_expression中所有大写字母转换成小写字母;返回值 类型为varchar LTRIM(character_expre- ssion) 将字符串表达式character_expression中的前导空格删除;返回值类型为varchar NCHAR(integer_ expression) 返回整数表达式integer_expression所代表的Unicode字符;返回值类型为 nchar(1) PATINDEX('%pattern%', expression) 返回表达式expression中pattern首次出现的位置;返回值类型为int REPLACE('string_expre- ssion1','string_expression 2', 'string_expression3') 将字符串表达式string_expression1中所有string_expression2字符串替换为 string_expression3。QUOTENAME('character_string'['quote_character])给字符串 character_string添加上定界符,以构成SQL Server中有效的定界标识符;返回 值类型为nvarchar(129) REPLICATE(character_ expression,integer_ expression) 将字符串表达式character_expression重复integer_expression次,组成一个字符 串;返回值类型为varchar REVERSE(character_ expression) 将字符串表达式character_expression中字符逆向排列组成字符串;返回值类型 为varchar RIGHT(character_expres- sion,integer_expression) 返回字符串表达式character_expression中右边integer_expression个字符;返回 值类型为varchar RTRIM(character_ expression) 将字符串表达式character_expression中的尾部空格删除;返回值类型为varchar SOUNDEX(character_ expression) 返回一个四字符代码,说明字符串读音的相似性;返回值类型为char SPACE(integer_ expression) 返回一个由空格组成的字符串,空格的个数为integer_expression个;如果 integer_expression的值为负,返回NULL 387 附录C Appendix C Server的内置函数 (续表) 函数 说明 STR(float_expression [,legth[,decimal]]) 将一个数值型数据表达式float_expression转换为字符串,其中length为字符串 的总长度,decimal为小数点后要保留的位数;返回值类型为char STUFF(character_ expression1,start,length, Character_expression2) 删除指定长度的字符串,并在删除位置插入新的字符串,其中删除的字符串 为表达式character_expression1,插入的字符串为表达式character_expres- sion2, 删除的起始位置由参数start确定,删除的字符串长度为length SUBSTRING(expression, start,length) 返回表达式expression中从start位置开始长度为length的字符串;其中expression 可以为字符串、二进制、文本或图像数据类型 UNICODE(ncharacter_ expression) 返回Unicode表达式ncharacter_expression中第一个字符的整数值;返回类型为 int UPPER(character_ expression) 将字符串表达式character_expression中所有小写字母转换成大写字母;返回值 类型为varchar C.10 系统函数 系统函数返回有关Microsoft SQL Server的设置和对象等信息。SQL Server提供的系统函 数如表C.13所示。 表C.13 系统函数 函数 说明 APP_NAME() 返回当前会话的程序名称。返回值为类型nvarchar(128) CAST(expression AS data_type) 将表达式expression的数据类型转换为另外一种data_type的数据类型 CONVERT(data_type[(length), Expression[,style]]) 和CAST函数功能类似,将expression的数据类型转换为data_type的数据 类型,其中length是nchar、nvarchar、char、varchar、binary或varbinary 数据类型的可选项,style是datetime或smalldatetime转换为字符类型数 据,或者将float、real、money或smallmoney转换为字符类型数据时的 可选项,来说明数据转换格式 COALESCE(expression[,…n]) 返回所有参数中第一个非空表达式 COLLATIONPROPERTY( collation_name,property) 返回给定的校验的属性。其中collation_name为校验名,是nvarchar(128) 类型的数据,且不能为空;property是校验的属性,property的取值可 以为:CodePage为校验的非Unicode代码页,LCID为校验的Windows LCID,对SQL校验返回NULL值,ComparisonStype为校验的Windows对 照式样,对二进制或SQL校验返回NULL值 CURRENT_TIMESTAMP 返回当前的日期和时间,相当于函数GETDATE();返回值类型为 datetime CURRENT_USER 返回当前用户名称,相当于函数USER_NAME() DATALENGTH(expression) 返回表达式expression的子节数。返回值类型为int @@ERROR 返回上次执行的SQL-Transact语句时的错误数。返回值为整型 新概念 SQL Server 2005 教程 388 (续表) 函数 说明 fn_helpcollations() 返回SQL Server 2005支持的所有校验表。返回值为一个表,改表由name 和Desctiption两列组成,其中name为校验名称,Description为校验说明 fn_servershareddrives() 返回主服务器使用的共享驱动器的名称,返回值为一个表,该表由 DriveName列组成 FORMATMESSAGE(msg_ number,param_value[,…]) 使用sysmessages 系统表中已用的消息构造另外一个消息。 FOMATMESSAGE函数和RAISERROR语句相似,只是RAISERROR将 消息立刻输出,而msg_number为sysmessages系统表中存储的消息的 ID,如果该消息不存在,则返回NULL值,param_value为消息中使用 的参数,参数的最大个数为20。返回值类型为nvarchar GETANSINULL(['database']) 返回当前会话中,数据库的默认空值设置。返回值类型为int (HOST_ID() 返回主机标识号;返回值类型为char(8) HOST_NAME() 返回主机名称;返回值类型为nchar IDENT_CURRENT('table_ name') 返回任何会话中对指定表生成的最新的IDENTITY值,返回值类型为 sql_variant,IDENT_INCR('table_or_view')返回表或视图中IDENTITY 字段的增量值,返回值类型为numeric IDENT_SEED('table_or_view') 返回表或视图中IDENTITY字段的基数值;返回值类型为numeric @@IDENTITY 返回最新插入的IDENTITY字段值;返回值类型为numeric IDENTITY(data_type[,seed, increment]) Ascolumn_name 在SELECT语句中,和INTO从句一起使用,为新的表增添一个identity 字段;其中data_type为新增字段的数据类型,seed为基数值,increment 为增量,column_name为字段名 ISDATE(expression) 判断表达式的值是否为有效日期类型;返回值类型为int;如果返回值为 1,表示为有效日期类型;如果为0,表示为无效日期类型 ISNULL(check_expression, replacement_value) 用参数replacement_value的数值来代替表达式check_expression中的 NULL值,ISNUMERIC(expression)判断表达式expression的值是否为有 效numeric类型;返回值类型为int。如果表达式的值为整数、浮点数、 money或decimal数据类型,则返回值为1,否则为0 NEWID() 创建一个uniqueidentifier类型的数据 NULLIF(expression1, expression2) 如果表达式expression1和expression2的值相等,则返回NULL,否则返 回expression1的值 PARSENAME('objectname', object_piece) 返回一个对象名称中指定的部分。其中objectname为对象名称, object_piece为要返回的部分,其取值可以为;1表示返回对象名称;2 表示返回所有者名称;3表示返回数据库名称;4表示返回服务器名称 PERMISSIONS([objected [,'column']]) 返回一个位映射值,指出当前用户所具有的语句许可、对象许可或列 许可;返回值类型为int;若没有指定objectid,返回值所映射的用户许 可如表C.14所示;若objectid和column都指定,返回值所映射的用户许 可如表C.15所示;若只指定了objectid,返回值所映射的用户许可如表 C.16所示 @@ROWCOUNT 返回上一个语句所处理的行数。返回值数据类型为int TOWCOUNT_BIG() 返回上一个语句所涉及的行数。返回值数据类型为bigint 389 附录C Appendix C Server的内置函数 (续表) 函数 说明 SCOPE_IDENTITY() 返回在同样的范围内,插入identity字段的最新的identity值。返回值类 型为sql_variant,SERVERPROPERTY(propertyname)返回服务器句柄的 属性信息,其中propertyname为属性,其取值如表C.17所示,返回值为 sql_variant类型 SESSIONPROPERTY(option) 返回一个会话的SET选项设置。option是会话的当前选项设置,option 取值可以为ANSI_NULLS、ANSI_PADDING、ANSI_WARNINGS、 ARITHABORT、CONCAT_NULL_YIELDS_NULL、NUMERIC_ ROU- NDABORT、QUOTED_IDENTIFIER和其他字符串。返回值类型为 sql_variant,如果为1表示ON;如 果 为 0表示OFF;如果为NULL则表示为 无效输入 SESSION_USER 返回当前会话的数据库用户名称,返回值为nchar型 STATS_DATE(table_id,index_ id) 返回指定索引的统计表最后一次被修改的日期,其中table_id为表的标 识号,index_id为索引标识号;返回值为datetime类型 SYSTEM_USER 返回当前登录的标识名称 @@TRANCOUNT 返回当前连接的有效事务数 USER_NAME([id]) 返回参数id指定的用户名;其中id为int型数据,返回值为nvarchar(256) 型数据;如果id缺省,则返回当前的用户名 注 意 CAST函数转换的数据类型data_type不能是用户定义的数据类型。 表C.14、表C.15和表C.16分别为没有指定objectid时、指定objectid和column时,以及只 指定objectid时,PERMISSIONS函数返回值所映射的用户许可。 表C.14 没有指定objectid时,PERMISSIONS函数返回值所映射的用户许可 返回位值(dec) 返回位值(hex) 语句许可 1 0x1 CREATE DATABASE(只对 master 数据库有效) 2 0x2 CREATE TABLE 4 0x4 CREATE PROCEDURE 8 0x8 CREATE VIEW 16 0x10 CREATE RULE 32 0x20 CREATE DEFAULT 64 0x40 BACKUP DATABASE 128 0x80 BACKUP LOG 256 0x100 Reserved 表C.15 指定了objectid和column时,PERMISSIONS函数返回值所映射的用户许可 返回位值(dec) 返回位值(hex) 语句许可 1 0x1 SELECT 2 0x2 UPDATE 4 0x4 REFERENCES 新概念 SQL Server 2005 教程 390 表C.16 只指定objectid时,PERMISSIONS函数返回值所映射用户许可 返回位值(dec) 返回位值(hex) 语句许可 1 0x1 SELECT ALL 2 0x2 UPDATE ALL 4 0x4 REFERENCES ALL 8 0x8 INSERT 16 0x10 DELETE 32 0x20 EXECUTE(只对存储过程有效) 4096 0x1000 SELECT ANY(至少要有一列) 8192 0x2000 UPDATE ANY 16384 0x4000 REFERENCES ANY SERVERPROPERTY函数的propertyname取值如表C.17所示。 表C.17 SERVERPROPERTY函数的propertyname取值 Propertyname取值 返回值 Collation 服务器的默认校验名;如果输入无效或者出现错误,则返回NULL值。数 据类型为nvarchar Edition 服务器上安装的SQL Server版本;返回值为'Desktop Engine'、'Developer Edition'、'Enterprise Edition'、'Enterprise Evaluation Edition'、'Personal Edition'、'Standard Edition',数据类型为nvarchar(128) EngineEdition 服务器上安装的SQL Server引擎版本。1:Personal或者Desktop Engine;2: Standard;3:Enterprise(Enterprise、EnterpriseEvaluation和Developer的返 回值)。数据类型为int InsranceName 用户连接的句柄名称。如果句柄名称为默认句柄、无效输入或出现错误, 则返回NULL。数据类型为nvarchar IsClustered 判断在主服务器中配置的服务器是否集成。1表示集成;0表示没有集成; NULL表示无效的输入或者出现错误。数据类型为int IsFullTextInstalled 判断当前的SQL Server中全文组件是否安装。1表示已经安装;0表示没有 安装;NULL表示无效的输入或者出现错误。数据类型为int IsIntegratedSecurityOnly 服务器是否处于完全安全模式。1表示完全安全;0表示非完全安全;NULL 表示无效的输入或者出现错误。数据类型为int IsSingleUser 数据类型为int,判断服务器是否为单用户模式。1表示单用户;0表示非单 用户;NULL表示无效的输入或者出现错误 IsSyncWithBackup 判断出版数据库或分布式数据库能否在不中断事务复制的情况下恢复。1 表示可以;0表示不可以。数据类型为int LicenseType 数据类型为nvarchar(128),表示SQL Server的模式。PER_SEAT为per_seat 模式;PER_PROCESSOR为per_processor模式;DISABLED为许可禁止 MachineName Windows NT的计算机名。对主服务器,在虚拟服务器上运行的SQL Server, 其返回值为虚拟服务器的名称;如果是无效的输入或者出现错误,则返回 NULL。数据类型为nvarchar 391 附录C Appendix C Server的内置函数 (续表) Propertyname 取值 返回值 NumLicenses 在 per_seat 模式下,为 SQL Server 上注册的客户许可数目;在 per_processor 模式下,为 SQL Server 上许可的处理器数目;如果服务器不是以上的模 式,则返回 NULL。数据类型为 int ProcessID SQL Server 服务的进程标识号。如果是无效的输入或者出现错误,则返回 NULL。数据类型为 int ProductVersion SQL Server 的版本,格式为:'major.minor.build'。数据类型为 varchar(128) ProductLevel 数据类型为 nvarchar(128),表示 SQL Server 版本的级别。'RTM'表示发行 版本;'SPn'表示服务组件版本;'Bn'表示测试版本 ServerName 服务器的名称。如果是无效的输入或出现错误,则返回 NULL。数据类型 为 nvarchar C.11 系统统计函数 系统统计函数返回系统的统计信息。SQL Server 2005提供的统计函数如表C.18所示 表C.18 系统统计函数 函数 说明 @@CONNECTIONS 返回自本次启动以来,接受的连接或试图连接的次数 @@CPU_BUSY 返回自本次启动以来,CPU工作的时间,单位为毫秒/ms @@IDLE 返回自本次启动以来,CPU空闲时间,单位为毫秒/ms @@IO_BUSY 返回自本次启动以来,CPU处理输入和输出操作的时间,单位为毫秒/ms @@PACKET_ERRORS 返回自本次启动以来,SQL Server中出现的网络数据包的错误数目 FN_VIRTUALFILESTA TS( [@DatabaseID=] database_id, [ @FileID = ] file_id ) 返回数据库文件的I/O统计表,包括日志文件;其中database_id为int类型数据, 代表数据库ID,file_id也为int类型数据,代表文件的ID;返回值为一个表,该表 由DBID、FileID、TimeStamp、NumberReads、NumberWrites、BytesRead、 BytesWritten和IoStallMS 8个字段组成,其中DBID和FileID字段的数据类型为 smallint,TimeStamp字段的数据类型为int,其他几个字段的数据类型为bigint;字 段DBID表示数据库的ID;FileID表示文件ID;TimeStamp表示获取数据的时间; NumberReads表示对文件发布的读命令数目;NumberWrites表示对文件发布的 写命令;Bytesread表示对文件发布的读取字节数;BytesWritten表示对文件发 布的写字节数;IoStallMS表示用户等待I/O的总时间,单位为毫秒/ms @@PACK_RECEIVED 返回自本次启动以来,通过网络读取的输入数据包数目。返回值类型为整型 @@PACK_SENT 返回自本次启动以来,通过网络发送的输出数据包数目。返回值类型为整型 @@TIMETICKS 返回一个计时单位的微秒数。操作系统中,一个计时单位是31.25ms。每个返 回值类型为整型 @@TOTAL_ERRORS 返回自本次启动以来,磁盘的读写错误次数。返回值类型为整型 @@TOTAL_READ 返回自本次启动以来,读磁盘的次数。返回值类型为整型 @@TOTAL_WRITE 返回自本次启动以来,写磁盘的次数。返回值类型为整型 新概念 SQL Server 2005 教程 392 C.12 文本和图像函数 图像函数对文本或图像的输入值或列执行操作,并返回相关信息。SQL Server 2005提 供的文本和图像函数如表C.19所示。 表C.19 文本和图像函数 函数 说明 PATINDEX PATINDEX 函数返回一个字符串在一个表达式中第一次出现的位置 TEXTPTR TEXTPTR 函数返回指向 text、ntext 或 image 字段首页数据的指针,返回值 类型为 varbinary。返回的指针可以在 READTEXT、WRITETEXT 和 UPDATETEXT 语句中使用 TEXTVALID TEXTVALID 函数检查所给的文本指针是否有效 注 意 如果表中没有行文本,并且也没有使用UPDATETEXT语句初始化text、ntext或image 字段,则TEXTPTR将返回null。 附录 D 课后练习参考答案 第 3 章 选择题和简答题参考答案 (1)A 因为1MB包含128个页面。而每个页面的前132字节作为页面头使用,所以实际上只有 8060个字节可以使用。每一笔记录为1024,所以每个页面只能包含7笔记录。所以1MB字节 只能包含128×7笔记录。因此数据库的大小应为100 000/(128×7)=120MB。 (2)D 不能创建小于model数据库容量的数据库。 (3)B 一个数据库可以跨越多个数据文件,不管他们是否位于同一个硬盘上。 (4)C 可以收缩数据库,以节省磁盘空间。 (5)有两种方法可以删除与其他表存在关联的表:一是先删除关联,然后删除表。另 外一种是在关系图窗口中,右击要删除的表,然后选择“从数据库中删除表”命令,并在 关闭关系图窗口时保存关系图。 第 4 章 选择题和简答题参考答案 (1)B 因为所有的用户都有Windows的账户,所以使用混合验证模式没有太大的意义,而使 用Windows验证模式则显得比较方便。 (2)A、D (3)A (4)A (5)A、B、C都能完成任务,但是A最省事。而D不能完成任务。 (6)A 因为所有数据库中的用户名和登录名的映射可能都不相同,所以每个数据库都包含自 己的sysusers表。 (7)略。 第 6 章 选择题和简答题参考答案 1. C 2. 略。 新概念 SQL Server 2005 教程 394 3. 略。 第 8 章 选择题和简答题参考答案 (1)B (2)强制视图上执行的所有数据修改语句都必须符合由select_statement设置的准则。 第 9 章 选择题和简答题参考答案 (1)略。 (2)创建和绑定。 (3)略。 (4)略。 第 10 章 选择题和简答题参考答案 1. A、B和C 2. A 3. 略。
还剩399页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

crazy4113

贡献于2015-06-29

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf