1、一、 实验题目: 1.将代码 1 的功能用语义等价的更新游标来实现 2.定义具有以下功能的存储过程(1)计算给定课程的总分数(2)统计给定课程的成绩分布情况,即按照各分数段统计人数;(= 3000 and salary = 4000UPDATE teachers SET salary=salary-200 WHERE current of my_cursorFETCH NEXT FROM my_cursor INTO tid, salary - 读取记录并推进游标ENDCLOSE my_cursor - 关闭游标DEALLOCATE my_cursor - 释放游标执行前教师部分表如下:执行后
2、教师表中对应部分如下:2. (1)先看第一个求总分的实验的解题过程:第一种方法如下:Create proc score_sum0class char(8),sum int outputAsselect sum =sum(score)from choicesgroup by cid having cid=class执行入下:Declare tal intEXEC score_sum 10021,tal outputPrint tal结果显示:第二种方法用游标做:Create proc score_sum( class char(10),sum int output)Asset sum=0DECL
3、ARE course char(10),score intDECLARE my_cursor CURSOR FOR - 声明游标SELECT cid, score FROM choicesOPEN my_cursor - 打开游标FETCH NEXT FROM my_cursor INTO course, score - 读取记录并推进游标WHILE fetch_status=0BEGIN IF course=class and score is not nullset sum =sum+ scoreFETCH NEXT FROM my_cursor INTO course, score -
4、读取记录并推进游标ENDCLOSE my_cursor - 关闭游标DEALLOCATE my_cursor return 0 执行如下:Declare tal intEXEC score_sum 10021,tal outputPrint tal结果显示:我们可以看到有不同的执行时间。(2) 统计给定课程的成绩分布情况create proc coutclass char(8),cc1 int output ,cc2 int output,cc3 int output,cc4 int output,cc5 int output,e int ,d int,c int,b int,a intass
5、elect cc1 =count(score) from choices where score=e and score=d and score=c and score=b and score=e and score=d and score=c and score=b and score=aexec grading 60,70,80,90,100 -按声明参数的顺序实验的结果确实是把各个分数段的等级标记了出来。3. 用三种方法来实现,并比较那三种方法:) 简单的语句:-SQL 查询select sname,count(cid) courses,sum(score) totalscorefrom
6、 choices c join students s on c.sid=s.sidgroup by c.sid,s.snamehaving c.sid=800002933) 用存储过程,但不用游标create proc querysid int,sname char(10) output,courses int output,scores int outputasselect sname=sname from students where sid=sidselect courses=count(cid)from choices c join students s on c.sid=s.sidg
7、roup by c.sid,s.snamehaving c.sid=sidselect scores=sum(score)from choices c join students s on c.sid=s.sidgroup by c.sid,s.snamehaving c.sid=sid调用过程如下:declare name char(10),ctotal int,stotal intexec query 800002933,name output,ctotal output,stotal outputprint name +num +sumprintname+convert(varchar,
8、ctotal)+convert(varchar,stotal)可以看到执行的结果如下: ) 用游标和存储过程Create proc querysidsid int ,sname char(10) output,courses int output,scores int outputAsset courses=0 set scores=0select sname=sname from students where sid=sidDECLARE studentid int,sc intDECLARE my_cursor CURSOR FOR - 声明游标SELECT sid,score FROM
9、choices OPEN my_cursor - 打开游标FETCH NEXT FROM my_cursor INTO studentid,sc - 读取记录并推进游标WHILE fetch_status=0BEGIN IF studentid=sid set courses=courses+1IF studentid=sid and sc is not nullset scores=scores+scFETCH NEXT FROM my_cursor INTO studentid,sc- 读取记录并推进游标ENDCLOSE my_cursor - 关闭游标DEALLOCATE my_curs
10、or return 0调用过程如下: declare name char(10),ctotal int,stotal intexec querysid 800002933,name output,ctotal output,stotal outputprint name +num +sumprint name+convert(varchar,ctotal)+ +convert(varchar,stotal)结果如下:根据上面对同一个学生的名字,选课数目,总分的三种方法对比,我们可以看到它们有很多不同的地方,首先是时间的长短很不相同:它们分别是:2 秒 3 秒 19 秒,然后实现的方法和代码长短都很不同。由此我认为,游标的执行时间比较长,效率较没有用游标的那两种方法略低。 三、 实验心得 首先,我觉得这次实验让我学到了很多知识。对存储过程,游标的使用和实现由了切身的体会,对其中要注意的一些问题也有了比较深刻的认识,比如在使用游标时用 IF语句中,要记住判断变量是否为 NULL,有些情况下这可能导致没有结果输出 其次,我对 PRINT 语句也有比较好的认识,在要输出多个结果时要注意要转换为VARCHAR 的类型再连续输出 还有,我认为以后可以多些用简单的 SQL 的语句,因为它的执行效率比较高,游标的耗时太长,在要一次编译多次使用时,可以用存储过程,它的实现和调用都比较方便。