存储过程、触发器和用户自定义函数实验兰州大学数据库实验报告实验内容一练习教材中存储过程、触发器和用户自定义函数的例子。教材中的BookSales数据库,在群共享中,文件名为BookSales.bak。实验内容二针对附件1中的教学活动数据库,完成下面的实验内容。1、存储过程(1)创建一个存储过程,该存储过程统计“高等数学”的成绩分布情况,即按照各分数段统计人数。CREATEProcMATH_NUM@MATHCHAR(20)='高等数学'ASSELECT@MATHascanme,count(casewhenscore=90then1end)as[90以上],count(casewhenscore=80andscore90then1end)as[80-90],count(casewhenscore=70andscore80then1end)as[70-80],count(casewhenscore=60andscore70then1end)as[60-70],count(casewhenscore60then1end)as[60以下]FROMstudy,courseWHEREstudy.cno=course.cnoandcourse.cname=@MATHGROUPBYcourse.cname运行结果:(2)创建一个存储过程,该存储过程有一个参数用来接收课程号,该存储过程统计给定课程的平均成绩。CREATEProcAVG_SCORE@cnoCHAR(5)ASSELECT@cnoas课程号,course.cnameas课程名,STR(AVG(score),5,2)as平均成绩FROMstudy,courseWHEREstudy.cno=course.cnoandcourse.cno=@cnoGROUPBYcourse.cname运行结果:(3)创建一个存储过程,该存储过程将学生选课成绩从百分制改为等级制(即A、B、C、D、E)。CREATEProcSCORE_CHANGEASSELECTcourse.cnameas课程名,study.snoas学号,study.cnoas课程号,study.scoreas成绩,casewhenscore=90andscore=100then'A'whenscore=80andscore90then'B'whenscore=70andscore80then'C'whenscore=60andscore70then'D'whenscore60then'E'endas'等级'fromstudy,coursewherestudy.cno=course.cno运行结果:(4)创建一个存储过程,该存储过程有一个参数用来接收学生姓名,该存储过程查询该学生的学号以及选修课程的门数。CREATEProcSTUDENT_STUDY@namechar(8)ASselect@nameas姓名,study.snoas学号,count(cno)as选修门数fromstudy,studentwherestudy.sno=student.snoandsname=@namegroupbystudy.sno运行结果:(5)创建一个存储过程,该存储过程有两个输入参数用来接收学号和课程号,一个输出参数用于获取相应学号和课程号对应的成绩。CREATEProcSTU_COR_SCORE@snochar(5),@cnochar(4),@wordsmallintoutputASselect@word=scorefromstudywheresno=@snoandcno=@cno运行结果:2、触发器(1)为study表创建一个UPDATE触发器,当更新成绩时,要求更新后的成绩不能低于原来的成绩。CREATETRIGGERUPDATE_SCOREONstudyinsteadofupdateasdeclare@sno2char(5),@cno2char(4),@score1smallint,@score2smallintselect@sno2=sno,@cno2=cno,@score2=scorefrominsertedselect@score1=scorefromdeletedif(@score2=@score1)updatestudysetscore=@score2wherestudy.cno=@cno2andstudy.sno=@sno2go运行结果:按要求sno=98604cno=C604score=85改成89不能改成85了(2)为study表创建一个DELETE触发器,要求一次只能从study表中删除一条记录。CREATETRIGGERDEL_STUDYONstudyinsteadofDELETEASbegindeclare@numint,@snochar(5),@cnochar(4)select@num=COUNT(*)fromdeletedif@num=1beginselect@sno=sno,@cno=cnofromdeleteddeletefromstudywhere@sno=study.snoand@cno=study.cnoendelseprint'一次不能删除多条记录'end运行结果:(3)为course表创建一个INSERT触发器,要求插入的课程记录中任课教师不能为空。CREATETRIGGERINSERT_CORONcourseinsteadofinsertASdeclare@cnochar(4),@cnamechar(20),@teacherchar(8)select@cno=cno,@cname=cname,@teacher=teacherfrominsertedif(@teacherisnull)print'注意:任课教师不能为空!'elseinsertcoursevalues(@cno,@cname,@teacher)运行结果:3、用户自定义函数(1)创建一个返回标量值的用户定义函数RectangleArea:输入矩形的长和宽就能计算矩形的面积。CREATEfunctionRectangleArea(@aint,@bint)returnsintASbeginreturn@a*@bend运行结果:(2)创建一个用户自定义函数,功能为产生一张有关学生成绩统计的报表。该报表显示每一门课程的课程号、课程名、选修人数、本门最高分、最低分和平均分。调用这个函数,生成相应的报表并给用户浏览。CREATEfunctionSTUDENT_TABLE()returnstableASreturn(selectstudent_course.cno课程号,course.cname课程名,COUNT(student_course.sno)选修人数,max(student_course.score)最高分,min(student_course.score)最低分,AVG(student_course.score)平均分fromstudent_course,coursewherestudent_course.cno=course.cnogroupbystudent_course.cno,course.cname)运行结果:实验数据库说明教学活动数据库包括student、course和study三个基本表,三个基本表的结构说明和数据如下:(1)学生表(student)学生表的结构列名数据类型长度是否允许为空值字段说明snochar5NO学号snamechar8NO姓名agesmallint年龄sexnchar1性别说明:sno为主键,age的范围为15~35之间,sex只能为“男”或“女”。学生表的记录snosnameagesex98601李强20男98602刘丽21女98603张兵20男98604陈志坚22男98605王颖21女(2)课程表(course)课程表的结构列名数据类型长度是否允许为空值说明cnochar4NO课程号cnamechar20NO课程名teacherchar8任课教师说明:cno为主键。课程表的记录cnocnameteacherC601高等数学周振兴C602数据结构刘建平C603操作系统刘建平C604编译原理王志伟(3)选课表(study)选课表的结构列名数据类型长度是否允许为空值说明snochar5NO学号cnochar4NO课程号scoresmallint成绩说明:sno和cno为主键,sno为外键(参照student表的sno),cno为外键(参照course表的cno),score的范围为0~100之间。选课表的记录snocnoscore98601C6019098601C6029098601C6038598601C6048798602C6019098603C6017598603C6027098603C6045698604C6019098604C6048598605C6019598605C60380