SQL Server 2005 实用教程
description
Transcript of SQL Server 2005 实用教程
SQL Server 2005 实用教程
电子工业出版社 出版
第 10 章
程序设计
3
第 10 章 SQL Server 中的程序设计 10.1 程序中的批、脚本、注释
10.2 SQL Server 变量
10.3 程序中的流程控制
10.4 SQL SEVER 函数
10.5 程序中的事务
10.6 游标的使用
10.7 案例应用举例
4
10.1 程序中的批、脚本、注释
1 . 批处理
批处理就是一个或多个 Transact-SQL 语句的集合,从应用程序—次性发送到 SQL Server 并由 SQL Server 编译成—个可执行单元,此单元称为执行计划。建立批处理时,使用 GO 语句作为批处理的结束标记。
5
10.1 程序中的批、脚本、注释建立批处理时,应当注意以下几点: CREATE DEFAULT , CREATE PROCEDURE , CREATE RULE , CREATE TRIGG
ER 及 CREATE VIEW 语句不能与其他语句放在一个批处理中。 不能在删除一个对象之后,在同一批处理中再次引用这个对象。 不能在一个批处理中引用其他批处理中所定义的变量。 不能把规则和默认值绑定到表字段或用户自定义数据类型之后,立即在同—个批处
理中使用它们。 不能定义一个 CHECK 约束之后,立即在同一个批处理中使用该约束。 不能在修改表中的一个字段名之后,立即在同一个批处理中引用新字段名。 如果一个批处理中的第一个语句是执行某个存储过程的 EXECUTE 语句,则 EXEC
UTE 关键字可以省略;如果该语句不是第一个语句,则必须使用 EXECUTE 关键字,或者省写为“ EXEC” 。
6
10.1 程序中的批、脚本、注释2 . 脚本 脚本是存储在文件中的一系列 SQL 语句,即一系列按顺序提交的
批处理。 SQL 脚本中可以包含一个或多个批处理。使用脚本可以将创建和维护数据库时的操作步骤保存为一个磁盘文件。将 Transact-SQL 语句保存为脚本文件,不仅可以建立起可再用的模块化代码,还可以在不同计算机之间传送 Transact-SQL 语句,使两台计算机执行同样的操作。脚本可以在查询分析器中执行,也可以在 isql 或 osql 实用程序中执行。
7
10.1 程序中的批、脚本、注释
3. 注释
注释是程序代码中不执行的文本字符串(也称为注解)。在 SQL Server 中,可以使用两种类型的注释字符:一种用于单行注释的注释符“ --” ,另一种是块注释,注释符号为“ /* */” 。
8
10.2 SQL Server 变量
变量是 SQL Server 用来在语句之间传递数据的方式之一。 SQL
中有两种形式的变量,一种是系统提供的全局变量,另外一种
是用户自己定义的局部变量。
9
1. 全局变量
全局变量是 SQL Server 系统提供并赋值的变量。用户不能建立全局变量,也不能修改全局变量。在 SQ
L Server 2000 中,全局变量是—组特殊的函数,它们的名称是以 @@ 开始,而且不需要任何参数,在调用时无需在函数名后面加上—对圆括号,这些函数也称为无参函数。
10
2. 局部变量
局部变量是指在批处理或脚本中用来保存数据值的对象。局部变量常用于作为计数器计算循环执行的次数或控制循环执行的次数,也可以用于保存由存储过程代码返回的数据值。此外,还可以使用 Table 数据类型的局部变量来代替临时表。
11
2. 局部变量
1 )声明局部变量语法格式为: DECLARE @ 局部变量 数据类型 [,…n]
2 )局部变量赋值语句,语法格式如下: ①SET @ 局部变量 = 表达式 [,…n]
② SELECT @ 局部变量 = 表达式 [,…n]
3 )局部变量的作用域 局部变量的作用域从声明它们的地方开始到声明 它们
的批处理或存储过程的结尾。
12
10.3 程序中的流程控制
流程控制语句是用来控制程序执行和流程分支的命令,这些命令包括条件控制语句,无条件转移语句和循环语句。使用这些命令,可以使程序具有结构性和逻辑性,并可完成较复杂的操作。
13
10.3 程序中的流程控制
10.3.1 BEGIN…END 语句块
10.3.2 IF…ElSE 语句
10.3.3 CASE 表达式
10.3.4 WAITFOR 语句
10.3.5 WHILE 语句
10.3.6 PRINT 语句
10.3.7RETURN 语句
14
10.3.1 BEGIN…END 语句块
在条件和循环等流程控制语句中,要执行两个或两个以上的 Transact-SQL 语句时,就需要使用 BEGIN…END语句,这些语句可以作为一个单元来执行。其语法形式为:
BEGIN
语句 I
语句 2
…
END
15
10.3.1 BEGINN…END 语句块
BEGIN…END 语句通常用于下列情况:
WHILE 循环需要包含语句块。
CASE 语句的元素需要包含语句块。
IF 或 ELSE 子句需要包含语句块。
16
10.3.2 IF…ElSE 语句 在程序中,经常需要根据特定条件指示 SQL Server 执行不同的操
作和运算,进行流程控制。 SQL Server 利用 IF…ELSE 命令使程序有不同的条件分支,从而完成各种不同条件环境下的操作。其语法形式为:
IF 布尔表达式 语句 1
[ELSE
语句 2]
17
10.3.2 IF…ElSE 语句案例:使用 IF…ELSE 语句实现以下功能:如果存在职称为副教授或教授的教师,那么
输出这些教师的姓名、学历、职称,否则输出“没有满足条件的教师”信息。代码如下:
USE student
GO
IF EXISTS (SELECT * FROM 教师 WHERE 职称 =' 副教授 ' OR 职称 =' 教授 ')
BEGIN
PRINT ' 以下教师是具有高级职称的 '
SELECT 姓名 , 学历 , 职称 FROM 教师 WHERE 职称 =' 副教授 ' OR 职称 =' 教授 '
END
ELSE
BEGIN
PRINT ' 没有满足条件的教师 '
END
GO
18
10.3.3 CASE 表达式
CASE 表达式是一个特殊的 Transact-SQL 表达式,它能够实现多重选择的情况。 CASE 表达式不同于—个普通的 Transact-SQL 语句,它不能单独执行,而只能作为—个可以单独执行的语句的一部分来使用。 CASE 表达式分为简单 CASE 表达式和搜索 CASE 表达式两种类型。
19
10.3.3 CASE 表达式 1 .简单 CASE 表达式 简单 CASE 表达式将一个测试表达式与一组简单表达式进行比较,
如果某个简单表达式与测试表达式的值相等,则返回相应结果表达式的值。简单 CASE 表达式的语法格式为:
CASE测试表达式 WHEN测试值 1 THEN 结果表达式 1 [WHEN测试值 2THEN 结果表达式 2 [… ]] [ELSE 结果表达式 n] END
20
10.3.3 CASE 表达式 案例:使用简单 CASE 表达式实现以下功能:分别输出课程号和课程名称,
而且在课程名称后添加备注。代码如下:USE student
GO
SELECT 课程号 ,课程名称 ,备注 =
CASE 课程名称 WHEN 'SQL Server 2005 ' THEN ' 数据库应用技术 '
WHEN 'ASP.NET 程序设计 ' THEN 'WEB 程序设计 '
WHEN ' 计算机基础 ' THEN ' 计算机导论 '
WHEN '网络营销 ' THEN '电子商务 '
END
FROM 课程GO
21
2 .搜索 CASE 表达式 与简单 CASE 表达式相比较,在搜索 CASE 表达式中, CASE
关键字后面不跟任何表达式,各个 WHEN 子句后都是布尔表达式。搜索 CASE 表达式的语法格式为:
CASE WHEN 布尔表达式 1 THEN 结果表达式 1 WHEN 布尔表达式 2 THEN 结果表达式 2 […n ]] [ELSE 结果表达式 n] END
22
2 .搜索 CASE 表达式 案例:使用搜索 CASE 表达式实现以下功能:分别输出班级代码、班级
名称,并根据班级代码判别年级。代码如下:USE student
GO
SELECT 班级代码 ,班级名称 ,年级 =
CASE
WHEN LEFT(班级名称 ,2)='04' THEN '三年级 '
WHEN LEFT(班级名称 ,2)='05' THEN '二年级 '
WHEN LEFT(班级名称 ,2)='06' THEN ' 一年级 '
END
FROM 班级GO
23
10.3.4 WAITFOR 语句
WAITFOR 语句可以暂停执行程序—段时间之后再继续执行,也可以暂停执行程序到所指定的时间后再继续执行。 WAITFOR 语句的语法格式为:
WAITFOR DELAY ‘ 时间’ |TIME ‘ 时间’
24
10.3.4 WAITFOR 语句 案例:设置在输出系部代码为“ 01” 的班级信息后 5秒钟输出系部代码为“ 02” 的班级信息。代码如下:
USE student
GO
SELECT * FROM 班级 WHERE 系部代码 ='01'
GO
WAITFOR DELAY '00:00:05'
SELECT * FROM 班级 WHERE 系部代码 ='02'
GO
25
10.3.5 WHILE 语句 在程序中当需要多次重复处理某项工作时,就需使用 WHILE 循环
语句。 WHILE 语句的语法格式为: WHILE 布尔表达式 BEGIN
语句序列 1
[BREAK]
语句序列 2
[CONTINUE]
语句序列 3
END
26
10.3.5 WHILE 语句 案例:使用 WHILE 语句实现以下功能:求 2~300 之间的所有素数。DECLARE @I INT, @J INT
SET @I=2
WHILE @I<=300
BEGIN
SET @J=2
WHILE @J<=@I-1
27
10.3.5 WHILE 语句 BEGIN IF @I%@J=0 BREAK ELSE SET @J=@J+1 END IF @I=@J PRINT CONVERT(VARCHAR,@I)+' 是素数! ' SET @I=@I+1 END
28
10.3.6 PRINT 语句 SQL Server 向客户程序返回信息的方法除了使用 SELECT 语句外,还
可以使用 PRINT 语句,它的语法格式为: PRINT ‘ 字符串’ | 局部变量 | 全局变量 例 11.6 PRINT 语句举例。 USE STUDENT GO DECLARE @STR CHAR(20) SET @STR=”欢迎使用 PRINT 语句” PRINT @STR GO
29
10.3.7 RETURN 语句 RETURN 的作用是无条件终止查询、存储过程或批处理
等。可以在任意位置使用 RETURN 语句,以便从语句块中退出。使用 RETURN 语句时要注意,该语句后面存在的语句都不会被系统执行。当 RETURN 语句用于存储过程时,它不能返回空值。如果某个过程试图返回空值,则将生成警告消息并返回 0 值。
30
10.4 SQL Server 函数
为了使用户对数据库进行查询和修改时更加方便, SQL server
在 T-SQL 语言中提供了许多内部函数以供调用。用户也可以根据
自己的需要创建函数。系统提供的函数称为内置函数;用户创建的
函数称为用户自定义函数 。
31
10.4 SQL Server 函数
10.4.1 常用系统函数
10.4.2 创建自定义函数
10.4.3 修改和删除自定义函数
32
10.4.1 常用系统函数 系统函数为三类:标量函数、聚合函数和行集函数。
标量函数:对单一值操作,返回单一值。 聚合函数:对一组值进行计算后,向调用者返回单一的值。 行集函数:返回对象,该对象可在 SQL 语句中用作表引用。
对于每一个系统函数需要掌握两点: 函数功能 调用形式 < 参数个数及其作用 >
33
1 标量函数 数学函数 1 、求绝对值函数
调用形式: abs( 数值型表达式 )
功能:返回表达式 的绝对值,其值的数据类型与参数一致。
2 、求 ASCLL 码函数
调用形式: ascii( 字符 )
功能:返回字符的 ASCLL 码值,值的类型为整型。
34
1 标量函数
数学函数 3 、 ceiling( 数值型表达式 )
功能:返回最小的大于或等于给定数值型表达式的整数值,值的类型和给定的值相同。
4 、 floor( 数值型表达式 )
功能:返回最大的小于或等于给定数值型表达式的整数值。
35
1 标量函数 数学函数5 、 power( 表达式 1 ,表达式 2)
功能:进行乘方运算,求表达式的表达式 2 的次方,值的数据类型
和第一个参数的数据类型相同。
6 、 PI( )
功能:求圆周率。
7 、 sqrt( 表达式 )
功能:求表达式的平方根。
8 、 sign( 数值型表达式 )
功能:判断数值的正负属性, +1 表示正数; -1 表示负数。
36
1 标量函数 数学函数 9 、 rand( 整型表达式 )
功能:返回一个位于 0 和 1 之间的随机数,在单个查询中反复调用
rand( )将产生相同的值。
10 、 round( 数值表达式,整数 )
功能:将数值四舍五入成整数指定的精度形式。整数为正表示
要进行的运算位置在小数点后,为负表示在小数点前。
37
1 标量函数 字符串函数 1 、 len( 字符串表达式 )
功能:返回给定字符串表达式的字符个数,其中不包含尾随空格
,注意不是字节个数,返回类行为 int.
2 、 datalength( 表达式 )
功能:返回该表达式所占用的字节数,返回类型为 int 。对 varchar
,text,image,nvarchar,ntext 数据类型特别有用,因为这些数
据类型可以存储可变长数据。
38
1 标量函数 字符串函数 3 、 char( 整形表达式 )
功能:将给定的整形表达式的值按照 ASCLL 码转换为字符型。整
形表达式的值介于 0~255 之间,否则返回 null 。
4 、 substring( 字符串, star , length)
功能:从字符串的 star位置返回长度为 length 的字符串。
5 、 left( 字符型表达式,整形表达式 )
功能:返回从字符串左边开始指定个数的字符。
right( 字符型表达式,整形表达式 )
功能:返回从字符串右边开始指定个数的字符。
39
1 标量函数
字符串函数 6 、 upper( 字符型表达式 )
功能:将字符型表达式全部转化为大写形式。
lower( 字符型表达式 )
功能:将字符型表达式全部转化为大写形式。
7 、 ltrim( 字符型表达式 )
功能:删除左端空白。
rtrim( 字符型表达式 )
功能:删除右端空白。
40
1 标量函数
字符串函数 8 、 str(float 型表达式,长度 1 ,长度 2 ) 功能:将 float 型表达式转化为给定形式的字符串。长度 1 表示总 长度且包含小书店,长度 2 表示小数点后边的位数。 例: print str(123.45 , 6 , 1 ) 转换为有六个位置的字符串,小数部分四舍五入。 print str(123.45 , 2 , 2 ) 当表达式超出指定长度时,返回 * . *
41
1 标量函数
日期型函数 1 、 getdate( )
功能:返回当前的系统时间。 2 、 datepart(datepart , date)
功能:以整数的形式返回给定的 date 型数据的指定日期部分。 datename(datepart , date)
功能:以字符串的形式返回给定的 date 型数据的指定日期部分。 datepart 的取值 _____P305
3 、 day(date) 返回指定日期 day 部分的数值。 month(date) 返回指定日期month 部分的数值。 year(date) 返回指定日期 year 部分的数值。
42
2 聚合函数
SQL Server 提供了十几个聚合函数,下面我们将介绍几个最常用的聚合函数: COUNT(*) :用于计算所有行数
MIN( 数值表达式 ) :用于计算表达式的最小值
MAX( 数值表达式 ) :用于计算表达式的最大值
SUM( 数值表达式 ) :用于计算表达式的和
AVG( 数值表达式 ) :用于计算表达式的平均值
43
2 聚合函数 例: 使用聚合函数统计 STUDENT 数据库中学生的成 绩情况。其程序清单如下: USE STUDENT GO SELECT COUNT(*)AS 课程门数 ,MAX( 成绩 )AS 最高分 数 ,MIN( 成绩 )AS 最低分数 , SUM( 成绩 )AS 总成绩 ,AVG( 成绩 ) AS 平均成绩 FROM 课程注册 GROUP BY 学号 GO
44
10.4.2 用户自定义函数
在 SQL Server 中,用户不仅可以使用标准的内置函数,也可以使用自己定义的函数来实现一些特殊的功能。用户自定义函数可以在企业管理器中创建,也可以使用 CREATE FUNCTION 语句创建。在创建时需要注意:函数名在数据库中必须唯一,其可以有参数,也可以没有参数,其参数只能是输入参数,最多可以有 1024 参数。 标量函数:返回单个数据值。 表值函数:返回值是一个记录集合——表。在此函数中, return 语句包含一条单独的 select 语句。 多语句表值函数:返回值是由选择的结果构成的记录集。
45
10.4.2 用户自定义函数1、使用 CREATE FUNCTION 语句创建用户自定义函数使用 CREATE FUNCTION 创建用户自定义函数,其语法格式如下: CREATE FUNCTION [ owner_name.] function_name
( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] )
RETURNS scalar_return_data_type
[ AS ]
BEGIN
function_body
RETURN scalar_expression
END
46
10.4.2 用户自定义函数 function_name :指用户自定义函数的名称。其名称必须符合标识符的命名规则,
并且对其所有者来说,该名称在数据库中必须唯一。 @parameter_name :用户自定义函数的参数,其可以是一个或多个。每个函数
的参数仅用于该函数本身;相同的参数名称可以用在其它函数中。参数只能代替常量;而不能用于代替表名、列名或其它数据库对象的名称。函数执行时每个已声明参数的值必须由用户指定,除非该参数的默认值已经定义。如果函数的参数有默认值,在调用该函数时必须指定 "default" 关键字才能获得默认值。
scalar_parameter_data_type :参数的数据类型。 scalar_return_data_type :是用户定义函数的返回值。可以是 SQL Server 支持
的任何标量数据类型( text、 ntext、 image 和 timestamp 除外)。 function_body :位于 begin 和 end 之间的一系列 Transact-SQL 语句,其只用
于标量函数和多语句表值函数。 scalar_expression :用户自定义函数中返回值的表达式。
47
1. 标量函数例:在 studenet 库中创建一个用户自定义标量值函数 xuefen ,该函数通过输入成绩来判断是否取得学分,当成绩大于等于 60 时,返回取得学分,否则,返回未取得学分。代码如下:
USE studentGOCREATE FUNCTION xuefen(@inputxf int) RETURNS nvarchar(10) BEGIN declare @retrunstr nvarchar(10) if @inputxf >=60 set @retrunstr='取得学分 ' else set @retrunstr='未取得学分 ' return @retrunstr ENDGO
48
1. 标量函数
使用刚才定义的 xuefen 函数来查看课程号为“ 0004” 的课程,学生获得学分的情况。
在查询编辑器中输入如下代码:USE studenet
GO
SELECT 学号 , 成绩 ,dbo.xuefen( 成绩 ) AS 学分情况FROM 课程注册WHERE 课程号 ='0004'
GO
49
2. 表值函数表值函数遵循的原则: RETURNS子句仅包含关键字 table 。不必定义返回变量的格式,因为它由 RETURN 子句中
的 SELECT 语句的结果集的格式设置。 function_body 不由 BEGIN 和 END 分隔。 RETURN子句在括号中包含单个 SELECT 语句。 SELECT 语句的结果集构成函数所返回的表。内嵌表值函数中使用的 SELECT 语句受到与视图中使用的 SELECT 语句相同的限制。
例:在 STUDENT 库中创建一个内嵌表值函数 XUESHENG ,该函数可以根据输入的系部代码返回该系学生的基本信息。其代码如下:
CREATE FUNCTION XUESHENG(@inputxbdm nvarchar(4)) RETURNS table AS RETURN ( SELECT 学号 , 姓名 , 入学时间 FROM 学生 WHERE 系部代码 =@inputxbdm)GO建立好该内嵌表值函数后,就可以象使用表或视图一样来使用它:SELECT * FROM DBO.XUESHENG('01')GO
50
在 student 库中创建一个多语句表值函数 chengji ,该函数可以根据输入的课程名称返回选修该课程的学生姓名和成绩。代码如下:
USE studentGOCREATE FUNCTION chengji( @inputkc as char(20) )/* 为 chengji 函数定义的表结构,名称变量为 @chji */RETURNS @chji TABLE ( 课程名称 char(20), 姓名 char(8), 成绩 tinyint )ASBEGIN INSERT @chji /* 该变量是上面定义的表名称变量 */ SELECT c.课程名称 ,s.姓名 ,k. 成绩 FROM 学生 as s INNER JOIN 课程注册 as k ON s.学号 =k.学号 INNER JOIN 课程 as c ON c.课程号 =k.课程号 AND c.课程名称 =@inputkc RETURNENDGO
2. 表值函数
51
2. 表值函数在查询编辑器中输入以下查询命令:SELECT * FROM dbo.chengji('SQL Server 2005')
52
3. 多语句表值函数 多语句函数的主体中允许使用以下语句: 赋值语句。 制流语句。 DECLARE 语句,该语句定义函数局部的数据变量和游标。 SELECT 语句,该语句包含带有表达式的选择列表,其中的表达式
将值赋予函数的局部变量。 游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。只允许使用以 INTO子句向局部变量赋值的 FETCH 语句;不允许使用将数据返回到客户端的 FETCH 语句。
INSERT、 UPDATE 和 DELETE 语句,这些语句修改函数的局部 table 变量。
EXECUTE 语句调用扩展存储过程。
53
3. 多语句表值函数案例:在 student 库中创建一个多语句表值函数 chengji ,该函数可以根据输入的课程名称返回选修该课程的学生姓名和
成绩。代码如下:USE student
GO
CREATE FUNCTION chengji( @inputkc as char(20) )
/* 为 chengji 函数定义的表结构,名称变量为 @chji */
RETURNS @chji TABLE
(
课程名称 char(20),
姓名 char(8),
成绩 tinyint
)
AS
BEGIN
INSERT @chji /* 该变量是上面定义的表名称变量 */
SELECT c.课程名称 ,s.姓名 ,k. 成绩 FROM 学生 as s INNER JOIN 课程注册 as k
ON s.学号 =k.学号 INNER JOIN 课程 as c
ON c.课程号 =k.课程号 AND c.课程名称 =@inputkc
RETURN
END
GO
54
10.4.3 查看、修改和删除自定义函数 1. 查看用户自定义函数的属性在 SQL Server 中,根据不同需要,可以使用 sp_helptext、 sp_help 等系统存储过程来查看用户自定义函数的不同信息。每个系统存储过程的具体作用和语法如下:
使用 sp_helptext 查看用户定义函数的文本信息,其语法格式为: sp_helptext 用户自定义函数名使用 sp_help 查看用户自定义函数的一般信息,其语法格式为: sp_help 用户自定义函数名例:使用有关系统过程查看 STUDENT 数据库中名为 XUEFEN 的用户自定义函数的文本信息。其程序代码如下:
USE STUDENT GO SP_HELPTEXT XUEFEN GO
55
10.4.3 查看、修改和删除自定义函数2. 修改用户自定义函数的属性使用 SQL 命令修改用户自定义函数,使用 ALTER FUNCTION 命令可以修改用户自定义
函数。修改由 CREATE FUNCTION 语句创建的现有用户定义函数,不会更改权限,也不影响相关的函数、存储过程或触发器。其语法格式如下:
ALTER FUNCTION [ owner_name.] function_name ( [ { @parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ] ] ) RETURNS scalar_return_data_type[ AS ]BEGIN function_body RETURN scalar_expressionEND其中的参数与建立用户自定义函数中的参数意义相同。
56
10.4.3 查看、修改和删除自定义函数3. 使用 T-SQL 命令删除用户自定义函数使用 DROP 命令可以一次删除多个用户自定义函数,其语法格式为:
DROP FUNCTION [ 所有者名称 .] 函数名称 [,…n]
案例:删除在 student 库上建立的 xuefen 函数。代码如下:USE student
GO
DROP FUNCTION dbo.xuefen
GO
57
10.5 程序中的事务 1. 概述 1 )事务 事务是最小的工作单元。这个工作单元要么成功完成所有操作,
要么就是失败,并将所做的一切复原。 2 ) 事务特性 原子性( Atomic ) 一致性( ConDemoltent ) 独立性( Isolated ) 持久性( Durable )
58
10.5 程序中的事务 3 )事务类型 ※显式事务:显示事务是手工配置的事务。用保留字标识显式事务的开始和结束。 开始显式事务,首先输入关键词 BEGIN TRAN 。 结束显示事务,使用 COMMIT TRAN 。 取消事务,使用 ROLL BACK TRAN 命令。 ※隐式事务 :有时候看起来没有使用事务,但它们可能隐藏在幕后,这种事务叫做隐
式事务。要使用这种模式,必须使用 Set Implicit_Transactions On 语句来设置连接。 可以作为隐式事务的开始的与具有: ALTER TABLE、 CREATE、 DELETE、 D
ROP、 FETCH、 GRANT、 INSERT、 OPEN、 REVOKE、 SELECT、 TRUNCATE TABLE、 UPDATE 。
结束隐式事务,必须使用 COMMIT TRANSACTION 或 ROLLBACK TRANSACTION 语句。
59
10.5 程序中的事务
2 .检查点处理 1 ) 检查点 是 SQL Server 将数据页面从内存拷贝到磁盘时的内部处理点。 2 )检查点分类:自动检查点和手工检查点。 自动检查点是基于 SQL Server 计算的。可在 RECOVERY INT
ERVAL配置选项中规定检查点处理的频率。 手工检查点可在任何时候输入 Transact-SQL 命令 CHECKPOINT
来强制执行。只有 SA 或数据库的 DBA才能执行该命令。
60
10.5 程序中的事务
3 . 分布式事务
SQL Server 2000 可支持包括多于一台服务器的事务,它是用 MSDTC
( Microsoft 分布事务合作)服务来支持的。有 3 种方法可使用分布式事务:
1 )用 DB-Lib API (应用程序接口)编写分布事务程序,
2 )用 Transact-SQL 语法 BEGIN DISTRIBUTED TRANSACTION 。
3 )用 SET REMOTE_ PROC_ TRANSACTION 为单个会话启动分
布式事务。
61
10.5 程序中的事务
4 锁 锁用来提供数据库的并发性控制。 SQL Server 中有三类锁: 1 )共享锁:是加在正在读取的数据上的。 2 )更新锁:和独占锁很相似,更新锁防止别人在改变数据的过
程中修改数据。 3 )独占锁:当要改变数据时使用独占锁。它防止别的用户读取
或修改正在工作的数据。直到将锁释放为止,独占锁不与别的锁兼容。
62
10.5 程序中的事务5 .编写有效的事务 在进行事务设计时,需要遵循以下编写指导原则: 不要在事务处理期间要求用户输入。 在事务启动之前,获得所有需要的用户输入。 在浏览数据时,尽量不要打开事务。 在所有预备的数据分析完成之前,不应启动事务。 保持事务尽可能简短。 灵活使用更低的事务隔离级别。 灵活地使用更低的游标并发选项。 在事务中尽量使访问的数据量最小 尽量减少锁定的行数,从而减少事务之间的争夺。 小心地管理隐性事务,以便避免并发问题。
63
10.6 游标 游标是处理数据的一种方法,可以看作是一个表中的
记录的指针,作用于 SELECT 语句生成的记录集,能够实现在记录集中逐行向前或者向后访问数据。使用游标,可以在记录集中的任意位置显示、修改和删除当前记录的数据。
1.游标的基本操作游标的基本操作包含 5 部分内容:声明游标、打开游标、提取数据、关闭游标和释放游标。
64
1.游标的基本操作1 )声明游标游标在使用之前需要声明,以建立游标。声明游标的语法格
式为:DECLARE cursor_name CURSOR
[ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ]
FOR select_statement [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
65
1.游标的基本操作2 )打开游标创建游标之后,使用之前需要打开游标,才能从游标中提取
数据。打开游标的语法格式为:OPEN cursor_name
游标在打开状态下,不能再被打开,也就是 OPEN 命令只能打开已声明但尚未打开的游标。打开一个游标以后,可以使用全局变量 @@ERROR判断打开操作是否成功,如果返回值为 0 ,表示游标打开成功,否则表示打开失败。当游标被成功打开时,游标位置指向记录集的第一行之前。游标打开成功后,可以使用全局变量 @@CURSOR_ROWS 返回游标中的记录数。
66
1.游标的基本操作3 )提取数据游标被成功打开后,就可以使用 FETCH 命令从中检索特定
的数据。提取游标中数据的语法格式为:FETCH[[NEXT|PRIOR|FIRST|LAST|ABSOLUTE{n}|RELAT
IVE{n}]FROM] cursor_name [ INTO @Variable_name [ ,...n ] ]
67
1.游标的基本操作4 )关闭游标游标使用完毕后,应该关闭游标,释放当前结果集,以便释
放游标所占用的系统资源。关闭游标语法格式为:CLOSE cursor_name
关闭游标后,系统删除了游标中所有的数据,所以不能再从游标中提取数据。但是,可以再使用 OPEN 命令重新打开游标使用。在一个批处理中,可以多次打开和关闭游标。
68
1.游标的基本操作5 )释放游标如果一个游标确定不再使用时,可以将其删除,彻底释放游
标所占系统资源。释放游标的语法格式为:DEALLOCATE cursor_name
释放游标即将其删除,如果想重新使用游标就必须重新声明一个新的游标。
69
2. 使用游标案例:在 student 数据库,使用游标逐行显示“教师”表中的教师信息。代码如
下:USE studentGO-- 定义游标DECLARE c_jsxx CURSOR KEYSET FOR SELECT 姓名 , 性别 ,学历 FROM 教师
OPEN c_jsxx --打开游标DECLARE @xm nvarchar(8),@xb char(2),@xl nvarchar(10)IF @@ERROR=0 --判断游标打开是否成功BEGIN IF @@CURSOR_ROWS>0 BEGIN PRINT '共有教师 '+RTRIM(CAST(@@CURSOR_ROWS AS CHAR(3)))
+' 名,分别是: ' PRINT ''
70
2. 使用游标-- 提取游标中第一条记录,将其字段内容分别存入变量中 FETCH NEXT FROM c_jsxx INTO @xm,@xb,@xl --检测全局变量 @@FETCH_STATUS ,如果有记录,继续循环 WHILE (@@FETCH_STATUS=0) BEGIN PRINT @xm+' , '+@xb+' , '+@xl -- 提取游标中下一条记录,将其字段内容分别放入变量中 FETCH NEXT FROM c_jsxx INTO @xm,@xb,@xl END ENDENDELSEPRINT '游标存在问题! 'CLOSE c_jsxx -- 关闭游标DEALLOCATE c_jsxx -- 删除游标GO
71
2. 使用游标案例:在 student 数据库,生成一张备份课程表,使用游标删除一门课
程,修改一门课程。代码如下:USE studentGOSELECT * INTO 课程备份 from 课程SELECT * FROM 课程备份GO-- 定义游标DECLARE c_xiugai CURSOR SCROLL DYNAMIC FOR SELECT *
FROM 课程备份OPEN c_xiugai --打开游标-- 提取第一条记录的内容FETCH FIRST FROM c_xiugai -- 删除第一条记录
72
2. 使用游标DELETE FROM 课程备份WHERE CURRENT OF c_xiugai-- 提取最后一条记录的内容FETCH LAST FROM c_xiugai -- 修改最后一条记录UPDATE 课程备份 SET 课程名称 ='大学语文 'WHERE CURRENT OF c_xiugaiCLOSE c_xiugai -- 关闭游标DEALLOCATE c_xiugai -- 删除游标GOSELECT * FROM 课程备份GO在查询编辑器中运行以上代码,结果如图 10.11 所示。
73
10.7 案例中的程序设计1. 创建名称为 AGE 的标量值函数在 student 数据库中创建一个名为 AGE 的标量值函数。调用函数时,输入出生日期和当前日期,函数将返回学生的年龄。
USE studentGOCREATE FUNCTION AGE(@出生日期 DATETIME,@当前日期 DATETIME)RETURNS TINYINTASBEGINRETURN DATEDIFF(YY,@出生日期 ,@当前日期 )ENDGOSELECT 姓名 ,DBO.AGE(出生日期 ,GETDATE()) AS 年龄 FROM 学生GO
74
10.7 案例中的程序设计2.创建名称为 XSCJ 的内联表值函数在 student 数据库中创建一个名为 XSCJ 的内联表值函数。调用函数时,输入课程号,该
函数将返回由学号、姓名、课程名和成绩组成的表。USE studentGOCREATE FUNCTION XSCJ(@inputzz nvarchar(20)) RETURNS table AS RETURN( SELECT A.学号 , A.姓名 , C.课程名称 ,B. 成绩 FROM 学生 AS A JOIN 课程注册 AS B ON A.学号 =B.学号 JOIN 课程 AS C ON B.课程号 =C.课程号 WHERE C.课程号 =@inputzz)GOSELECT * FROM XSCJ('0001')GO
75
10.7 案例中的程序设计3. 创建名称为 KCXF 的多语句表值函数在 student 数据库中创建一个名为 KCXF 的多语句表值函数,该函数可以根据输入的课程名称返回选修该课程的学生姓名、成绩和学分绩(其中
学分绩的计算调用了 xuefenji 自定义函数)。USE studentGOCREATE FUNCTION kcxf(@inputkc as char(20) )RETURNS @xfchji TABLE ( 课程名称 char(20), 姓名 char(8), 成绩 tinyint, 学分绩 char(20) )ASBEGIN INSERT @xfchji SELECT c.课程名称 ,s.姓名 ,k. 成绩 ,dbo.xuefenji( 成绩 ) FROM 学生 as s INNER JOIN 课程注册 as k ON s.学号 =k.学号 inner join 课程 as c on c.课程号 =k.课程号 WHERE c.课程名称 =@inputkc RETURNENDGOSELECT * FROM KCXF('ASP.NET 程序设计 ')GO