实验报告
一、实验目的:
?掌握游标的使用方法
?掌握使用游标逐行操作SELECT语句结果集的数据的技能
二、实验内容:
?游标声明
?打开游标
?读取数据
?关闭游标
?释放游标
三、实验步骤:
(一)使用游标的几个步骤:
1、声明游标。使用T-SQL语句生成一个结果集,并且定义游标的特征,如游标中的记录是否可以修改;
2、打开游标
3、推进游标指针,从游标的结果集中提取数据,从游标中检索一行或多行数据成为提取数据。
4、逐行处理游标指针所指向的行数据。
5、关闭和释放游标。
1、利用标准方式声明一个名称为“student”的游标
use 学生
declare student cursor
for
select Sno,Sname,Sbirthday
FROM student
WHERE Sbirthday=19
FOR READ ONLY
GO
open student // 打开
go
fetch next from student //从游标中读取数据
fetch next from student
go
close student // 关闭
deallocate student // 删除
2:声明一个名称为Xuanke的游标
/*声明一个名称为Xuanke的游标*/
DECLARE XUANKE CURSOR
DYNAMIC /*动态的,动力的*/
FOR
SELECT Sno,Degree
FROM SCORE
WHERE Cno='3-105'
FOR UPDATE OF Sno
GO
/*打开XUANKE游标*/
OPEN XUANKE
GO
/*从XUANKE游标中读取数据*/
FETCH NEXT FROM XUANKE
GO
/*关闭XUANKE游标*/
CLOSE XUANKE
/*删除XUANKE游标*/
DEALLOCATE XUANKE
3:声明一个游标,可前后滚动,可对选课表2中的成绩进行修改
/*声明一个游标,可前后滚动,可对选课表中的成绩进行修改
DECLARE XK CURSOR
FOR SELECT*FROM SCORE
FOR UPDATE OF Degree
/*打开游标XK*/
OPEN XK
SELECT'游标数据行数'=@@CURSOR_ROWS
/*
全局变量@@CURSOR_ROWS返回最后打开的游标中当前存在的合格行的数量。
返回值为-m,表示游标被异步填充。返回值-m是键集中当前的行数。
返回值为-1,表示游标为动态。因为游标可反映所有更改,所以符合游标的行数不断变化。因此永远不能确定地说所有符合条件的行均已检索到。
返回值为,没有被打开的游标,没有符合最后打开的游标的行,或最后打开的游标已被关闭或被释放。
返回值为n,游标已完全填充。返回值n是在游标中的总行数。
@@ROWCOUNT
返回受上一语句影响的行数。任何不返回行的语句将这一变量设置为.
*/
/*从游标XK中读取数据*/
FETCH NEXT FROM XK
/*关闭游标XK*/
close XK
deallocate XK
4:为学生表中姓“李”的同学的行声明游标,并使用FETCH NEXT逐个提取这些行。(SCOREROLL 指定所有的提取选项FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE均可使用)
/*为学生表中姓“李”的同学的行声明游标,并使用FETCH NEXT逐个提取这些行。(SCOREROLL 指定所有的提取选项FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE均可使用)
use 学生选课*/
DECLARE STU SCOREROLL CURSOR
FOR
SELECT Sname
FROM Student
WHERE Sname LIKE'李%'
ORDER BY Sname
GO
OPEN STU
FETCH NEXT FROM STU
WHILE@@FETCH_STATUS=0
BEGIN
FETCH NEXT FROM STU
END
close STU
/*
@@FETCH_STATUS返回针对连接当前打开的任何游标发出的上一条游标FETCH 语句的状态。
0 FETCH 语句成功。
-1 FETCH 语句失败或行不在结果集中。
-2 提取的行不存在
*/
5:创建一个SCOREROLL游标,使其通过LAST, PRIOR, RELATIVE, ABSOLUTE 选项支持所有滚动能力。
/*创建一个SCOREROLL游标,使其通过LAST, PRIOR, RELATIVE, ABSOLUTE 选项支持所有滚动能力。NEXT:返回当前行的下一行,并使其为当前行。如果FETCH NEXT是对游标的第一次提取操作,则返回结果集中的第一行。NEXT为默认的游标提取选项。
PRIOR:返回当前行的前一行,并使其为当前行。如果FETCH PRIOR是对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。
FIRST:返回游标中的第一行并将其作为当前行。
LAST:返回游标中的最后一行并将其作为当前行。
ABSOLUTE{n/@nvar}:如果n或@nvar为正数,返回从游标头开始的第n行并将返回的行变成新的当前行;如果n或@nvar为负数,返回游标尾之前的第n行并将返回的行变成新的当前行;如果n或@nvar为,则没有行返回。n必须为整形常量且@nvar必须为smallint, tinyint 或int。
RELATIVE{n/@nvar}:如果n或@nvar为正数,返回当前行之后的第n行并将返回的行变成新的当前行;如果n或@nvar为负数,返回当前行之前的第n行并将返回的行变成新的当前行;如果n或@nvar为,返回当前行;如果对游标的第一次提取操作时将FETCH RELATIVE 的n或@nvar指定为负数或,则没有行返回。n 必须为整形常量且@nvar必须为smallint, tinyint 或int。
use 学生选课*/
DECLARE STU SCROLL CURSOR for
select Sname,Sbirthday
FROM Student
open student
fetch last from student
fetch prior from student
fetch absolute 2 from student
fetch relative 3 from student
fetch relative -2 from student
deallocate STU
(二)使用游标修改数据
UPDATE和DELETE都是集合操作语句,如果只想修改或删除其中某个记录,则需要用带游标的SELECT 语句查出所有满足条件的记录,从中进一步找出要修改或删除的记录,然后用CURRENT形式的UPDATE 和
DELETE 语句修改或删除之。具体步骤:
1、用DECLARE语句声明游标,并指定FOR UPDATE OF column_name_list。
2、用OPEN语句打开游标。
3、用FETCH语句推进游标指针。
4、检查记录是否是需要修改或删除的记录。
5、处理完毕用CLOSE语句关闭游标。
用户可以在UPDATE 或DELETE 语句中使用游标来更新或删除表或视图中的行,但不能用来插入新行。
6:统计“数据结构”课程考试成绩的各分数段的分布情况。
declare course cursor
for
select Degree from SCORE
where Cno=(select Cno from Course
where Cname='计算机导论')
declare @p_100 smallint,@p_90 smallint,@p_80 smallint
declare @p_70 smallint,@p_60 smallint,@p_others smallint
declare @p_degree smallint
set @p_100=0
set @p_90=0
set @p_80=0
set @p_70=0
set @p_60=0
set @p_others=0
set @p_degree=0
open course
loop:
fetch next from course into @p_degree
if(@p_degree=100)set @p_100=@p_100+1
else if(@p_degree>=90)set @p_90=@p_90+1
else if(@p_degree>=80)set @p_80=@p_80+1
else if(@p_degree>=70)set @p_70=@p_70+1
else if(@p_degree>=60)set @p_60=@p_60+1
else set @p_others=@p_others+1
if(@@FETCH_STATUS=0)
goto loop
print str(@p_100)+','+str(@p_90)+','+str(@p_80)+','
print str(@p_70)+','+str(@p_60)+','+str(@p_others)
close course
deallocate course
7:定义一个游标,将学生表中所有学生的姓名、年龄显示出来。
go
declare @sname varchar(50),@Sbirthday date
declare stud SCroll cursor
for
select Sname,Sbirthday from Student
for read only
open stud
fetch from stud into @sname,@Sbirthday
while@@FETCH_STATUS=0
begin
print'学生姓名:'+@sname+' '+'学生出生日期:'+cast(@Sbirthday as char(10)) fetch from stud into @sname,@Sbirthday
end
close stud
deallocate stud
8:通过游标将学生表中第5位学生的年龄由19改为21
declare stu SCroll cursor
for
select Sname, Sbirthday from Student
for update of Sbirthday
open stu
fetch absolute 5 from stu
update Student
set Sbirthday='1998-08-08' where current of stu
fetch absolute 5 from stu close stu
deallocate stu