作业(附存储过程)
Posted Fmm-PMO
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了作业(附存储过程)相关的知识,希望对你有一定的参考价值。
小声嘟嘟:第5章留了一道题,第8章留了一道。本来是第8章的课后习题,老师留到了第5章,我当时还以为老师留错了,后来发现是我想多了。。第8章就留了一道题,一道题就够我想好久,而且是那种想了好久有的还没有结果的。。裂开
第5章课后习题题目描述:
假设有下面两个关系模式:
职工(职工号,姓名,年龄,职务,工资,部门号),其中职工号为主码;
部门(部门号,名称,经理名,电话),其中部门号为主码。
用SQL语言定义这两个关系模式,要求在模式中完成以下完整性约束条件的定义:
(1)定义每个模式的主码;(2)定义参照完整性;(3)定义职工年龄不得超过60岁。
开始写题
由于都是对属性的一些设置,所以可以在建表时一并处理,就将三问合成一个问题了
-- 部门表
create table Department(
Dno char(15) primary key, -- 部门号
Dname char(15) unique, -- 部门名称
Mname char(15) not null, -- 经理名
Phone char(15) not null -- 电话
);
-- 职工表
create table Employee(
Eno char(15) primary key, -- 职工号
Ename char(15) not null, -- 姓名
Eage int check(Eage > 0 and Eage <= 60) not null,-- 年龄
Duty char(15) not null, -- 职务
Salary float, -- 工资
Dno char(15) references Department(Dno) -- 部门号
);
第8章课后习题题目描述:
对学生—课程数据库编写存储过程,完成下述功能:
(1)统计离散数学的成绩分布情况,即按照各分数段统计人数。
(2)统计任意一门课的平均成绩。
(3)将学生选课成绩从百分制改为等级制(即A、B、C、D、E)。
开始写(让人头皮发麻、绞尽脑汁的)题
(0)准备工作
学生–课程数据库涉及三张表,分别是Student、Course、SC。之前的课程当中没有离散数学这门课,所以我临时添加,
insert into Course
values(8,'离散数学',NULL,3);
这里Cno为课程号,Cname为课程名,Cpno为先修课程的课程号,这里为了方便,不对离散数学的先修课进行设置,Ccredit为学分。
同时由于之前没有离散数学这门课,自然也就没有人选这门课,所以在SC表中添加离散数学的选课记录
insert into SC
values('201215123',8,81),('201215125',8,92),('201215121',8,75),('201215122',8,67);
准备工作完成,可以写题了
(1)统计离散数学的成绩分布情况,即按照各分数段统计人数。
①建立一张表GradeLevel,用来记录各个分数段的人数
由于第3问要分等级,且为5个,一般不及格算作一个等级,所以剩下的四个等级就把60~100按照以10个分数段为单位进行划分。
create table GradeLevel(
score char(10),
num int
);
insert into GradeLevel
values('[0,60)',0),('[60,70)',0),('[70,80)',0),('[80,90)',0),('[90,100]',0);
select * from GradeLevel;
②创建存储过程
if (exists (select * from sys.objects where name = 'Proc_GRADELEVEL'))
drop procedure Proc_GRADELEVEL
go
create procedure Proc_GRADELEVEL
as
begin
declare /*定义变量*/
@Cno char(4),
@less60 int, -- [0,60)
@more60less70 int,-- [60,70)
@more70less80 int, -- [70,80)
@more80less90 int, -- [80,90)
@more90less100 int -- [90,100]
-- 赋值
select @Cno = Cno from Course where Cname = '离散数学';
select @less60 = count(*) from SC where Grade < 60 and Cno = @Cno;
update GradeLevel set num = @less60 where score = '[0,60)';
select @more60less70 = count(*) from SC where Grade >= 60 and Grade < 70 and Cno = @Cno;
update GradeLevel set num = @more60less70 where score = '[60,70)';
select @more70less80 = count(*) from SC where Grade >= 70 and Grade < 80 and Cno = @Cno;
update GradeLevel set num = @more70less80 where score = '[70,80)';
select @more80less90 = count(*) from SC where Grade >= 80 and Grade < 90 and Cno = @Cno;
update GradeLevel set num = @more80less90 where score = '[80,90)';
select @more90less100 = count(*) from SC where Grade >= 90 and Grade < 100 and Cno = @Cno;
update GradeLevel set num = @more90less100 where score = '[90,100]';
end;
exec Proc_GRADELEVEL; -- 执行
select * from SC where Cno = 8;
select * from GradeLevel;
(2)统计任意一门课的平均成绩。
①建立一张表AvgGrade,用来记录每门课的平均成绩。
(这里只选取部分课程演示。。只选有成绩的)
create table AvgGrade (
Cname char(15), -- 课程名
AvgScore float -- 平均分
);
insert into AvgGrade
values('数据库', 0), ('数学', 0), ('信息系统', 0),('离散数学',0);
②创建存储过程
if (exists (select * from sys.objects where name = 'Proc_AVGSCORE'))
drop procedure Proc_AVGSCORE
go
create procedure Proc_AVGSCORE
as
begin
declare -- 定义变量
@AvgShujuku float,
@AvgShuxue float,
@AvgXinxixitong float,
@AvgLisan float;
-- 赋值
select @AvgShujuku = avg(Grade) from SC where Cno = '1';
update AvgGrade set AvgScore = @AvgShujuku where Cname = '数据库';
select @AvgShuxue = avg(Grade) from SC where Cno = '2';
update AvgGrade set AvgScore = @AvgShujuku where Cname = '数学';
select @AvgXinxixitong = avg(Grade) from SC where Cno = '3';
update AvgGrade set AvgScore = @AvgXinxixitong where Cname = '信息系统';
select @AvgLisan = avg(Grade) from SC where Cno = '8';
update AvgGrade set AvgScore = @AvgLisan where Cname = '离散数学';
end;
exec Proc_AVGSCORE;
select * from AvgGrade;
(3)将学生选课成绩从百分制改为等级制(即A、B、C、D、E)。
①选课成绩存在SC表中,可以给SC表增加一个属性列GradeLevel,用来显示该门成绩的等级(ABCDE)。
alter table SC
add GradeLevel char(2);
select * from SC;
②编写存储过程
注意在写等级划分的分数范围时,只能用and,>= <等这些符号,不能用between and,因为后者包括边界!!!
if(exists(select * from sys.objects where name = 'Proc_LEVEL'))
drop procedure Proc_LEVEL;
go
create procedure Proc_LEVEL
as
begin
update SC set GradeLevel = 'A' where Grade >= 90 and Grade <= 100;
update SC set GradeLevel = 'B' where Grade >= 80 and Grade < 90;
update SC set GradeLevel = 'C' where Grade >= 70 and Grade < 80;
update SC set GradeLevel = 'D' where Grade >= 60 and Grade < 70;
update SC set GradeLevel = 'E' where Grade >= 0 and Grade < 60;
end;
exec Proc_LEVEL; -- 执行
select * from SC;
总结:
这一道题都做了很长时间,而且是在百度+参考的基础上完成的,也通过这道题发现自己对存储过程,触发器这些语法的掌握不是很熟练,有待提高,T-SQL和标准SQL有很大不同,都掌握自然是好的。慢慢加油吧,始终怀着一颗谦卑的心,向更优秀的人和更优秀的自己靠近!
以上是关于作业(附存储过程)的主要内容,如果未能解决你的问题,请参考以下文章