数据库第5章作业(附存储过程)

小声嘟嘟:第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为学分。

数据库第5章作业(附存储过程)_第1张图片

同时由于之前没有离散数学这门课,自然也就没有人选这门课,所以在SC表中添加离散数学的选课记录

insert into SC
values('201215123',8,81),('201215125',8,92),('201215121',8,75),('201215122',8,67);

数据库第5章作业(附存储过程)_第2张图片

准备工作完成,可以写题了

(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;

数据库第5章作业(附存储过程)_第3张图片

②创建存储过程

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;

数据库第5章作业(附存储过程)_第4张图片

(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;

数据库第5章作业(附存储过程)_第5张图片

(3)将学生选课成绩从百分制改为等级制(即A、B、C、D、E)。

①选课成绩存在SC表中,可以给SC表增加一个属性列GradeLevel,用来显示该门成绩的等级(ABCDE)。

alter table SC
add GradeLevel char(2);

select * from SC;

数据库第5章作业(附存储过程)_第6张图片
②编写存储过程

注意在写等级划分的分数范围时,只能用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;

数据库第5章作业(附存储过程)_第7张图片

总结:
这一道题都做了很长时间,而且是在百度+参考的基础上完成的,也通过这道题发现自己对存储过程,触发器这些语法的掌握不是很熟练,有待提高,T-SQL和标准SQL有很大不同,都掌握自然是好的。慢慢加油吧,始终怀着一颗谦卑的心,向更优秀的人和更优秀的自己靠近!

你可能感兴趣的:(SQL,Server+C#)