数据库原理与应用实验四(以stuManage2为例)

1、说明下面代码段的功能

SELECT tname as ‘姓名’,tSex as ‘性别’,
case trank
when ‘教授’ then ‘高级职称’
when ‘讲师’ then ‘中级职称’
else
‘初级职称’
end
from teacher

从教师表中查询教师的姓名、性别、头衔等级,
其中“教授”的等级改为“高级职称”,“讲师”的等级改为“中级职称”,
其他教师的等级改为“初级职称”。

2、完成下面代码的书写

计算student_course表的平时分数列的平均值。
如果小于80,则分数增加其值的8%;如果分数的最高值超过95,
则终止该操作。在以下代码划线处填入适当的内容以完成上述功能。
update student_course set normalmark=60
go
while (select ________ (normalmark) from student_course)<80
begin
update student_course
set normalmark = normalmark *1.08
if (select max(normalmark) from student_course)>________
________
END

Update student_course set normalmark=60
go
WHILE (SELECT  avg(normalmark) FROM student_course)<80
BEGIN
UPDATE student_course
SET normalmark = normalmark *1.08
if (SELECT MAX(normalmark) FROM student_course)>95      
    break
END

3、根据要求完成下列题目

(1)编写一个触发器:在添加期末成绩信息时,
利用平时成绩、其中成绩和期末成绩来计算成绩总评。
如果没有期中成绩,则平时和期末成绩比重为2:8,
如果有期中成绩,则平时、期中、期末三者比重为2:2:6。
(假设表中有期中成绩列,且该列默认值为-1。)

--alter table student_course add qmmark int  --因为表中没有期末成绩,就增加进去
create trigger t1 on student_course
after update 
as
begin 
	declare @qzmark int
	declare @sno varchar(10)
	declare @ccno varchar(10)
	declare @qmmark int
	declare @exammark int
	declare @normalmark int
	select @exammark=ExamMark,@normalmark=NormalMark from deleted
	if @exammark is null
		begin set @exammark=0 end
	if @normalmark is null
		begin set @normalmark=0 end
	select @qmmark=qmmark from inserted
	if @qmmark is not null	
	begin
		select @sno=sNO,@ccno=ccNO from deleted
		select @qzmark=NormalMark from deleted
		if @qzmark=-1
			update student_course set Mark=@exammark*0.2+qmmark*0.8
								where sno=@sno and ccno=@ccno
--							and ExamMark is not null and qmmark is not null
		else
			update student_course set mark=@exammark*0.2+@normalmark*0.2+qmmark*0.6
								where sno=@sno and ccno=@ccno
	end
end
go

(2)编写一个触发器:当修改一个学生专业的时候(转专业),则自动将本学期新专业同学全都选修的课程给该同学选修。

--方法一
go
create trigger ChangeMajor1 on student
after update
as
begin
	declare @sno char(10)					--保存要修改专业的学生的学号
	declare @newmno char(6),@oldmno char(6) --要修改专业的学生的本来专业号和后来的专业号
	declare @term char(12)					--对应题目要求的本学期
	select @sno=sno,@newmno=mno from inserted	--从inserted表中找的学号和新专业号
	select @oldmno=mno from deleted				--从deleted表中找到旧的专业号
	if @newmno <> @oldmno						--如果该学生有转专业才执行触发器
		begin
			if month(getdate())>8
				set @term=str(year(getdate()),4,0)+'-'+str(year(getdate())+1,4,0)
			else
				set @term=str(year(getdate())-1,4,0)+'-'+str(year(getdate()),4,0)
			insert into student_course (sNO,ccNO)
			select @sno,sc.ccno
			from student_course as sc ,student as s,course_class as cc
			where sc.sNO=s.sNO and cc.ccNO=sc.ccNO and cc.Term=@term and s.mNO=@newmno
			group by sc.ccNO
			having count(*) =((select count(*) 
								from student
								where mno=@newmno)-1)
		end
	else
		begin
			print '专业没有变化'
			rollback transaction 
		end

end

--方法二
go
create trigger ChangeMajor2 on student
instead of update
as
begin
	declare @sno char(10)		--保存要修改专业的学生的学号
	declare @newmno char(6),@oldmno char(6) --要修改专业的学生的本来专业号和后来的专业号
	declare @term char(12)					--对应题目要求的本学期
	select @sno=sno,@newmno=mno from inserted	--从inserted表中找的学号和新专业号
	select @oldmno=mno from deleted				--从deleted表中找到旧的专业号
	if @newmno <> @oldmno						--如果该学生有转专业才执行触发器
	begin	
		if month(getdate())>8
			set @term=str(year(getdate()),4,0)+'-'+str(year(getdate())+1,4,0)
		else
			set @term=str(year(getdate())-1,4,0)+'-'+str(year(getdate()),4,0)
		insert into student_course(sNO,ccNO)
		select @sno,ccno
		from course_class as cc
		where cc.Term=@term and not exists 
						(select * from student as s
						where s.mNO=@newmno and not exists 
														(select * from student_course as sc
														where s.sNO =sc.sNO and sc.ccNO=cc.ccNO))
		update student set mNO=@newmno where sno=@sno

	end
	else
	begin
		print '专业没有变化'
		rollback transaction 
	end

end
go



/* 
这个是我不会做,然后做错的写法,当时好像没有看到student表中居然有一个专业的属性
不然感觉我也能做出来
create trigger ChangeMajor on student_course
after update
as
if exists	--证明要转专业
	(select * from inserted where ccNO not in
		(select ccNO from student_course where sNO='081220101')
	)
	--找出他要转的专业的ccno,就是班级号或者专业号
	select * from student_course where sNO=
	(select sNO from student_course where ccNO =
		(select ccNO from inserted)
	)
else
	select * from student
go
*/

(3)创建一个存储过程,利用输入的班级编号(学号前7位)和开课编号ccno,为全班所有同学自动选修该课程。

create procedure ChooseClass(@cno char(7) ,@ccno varchar(10) output)
as
begin 
 insert into student_course
select *,@ccno as ccno,null as NomalMark,null as ExamMark,null as Mark 
from student_course where ccNO=(
 select ccNO from course_class where cNO =@cno )
end
go

(4)创建一个带输入参数和输出参数的存储过程,要求实现如下功能:输入学生学号,然后输出学生的选课门数、平均分以及所选学分。

create procedure Selection1(@sno varchar(10) ,
@count int output ,@avgmark float output ,@weight int output)
as
begin

set @count=(select count(*) from 
(select ccno from student_course where sNO=@sno group by ccno) as jian)
set @avgmark =(select AVG(mark) from student_course where sNO='081220101' group by sNO)
set @weight=
(select SUM(credit) from (
select * from course_class where ccNO in (
select ccNO from student_course where sNO=@sno group by ccNO) ) as jane)
end
go

(5)调用4小题中的存储过程,并分别获得输出相关信息。

declare @count int
declare @avgmark int 
declare @weight int
exec Selection '081220101',@count output,@avgmark output, @weight output
select count =@count,avgmark =@avgmark,weight=@weight

4、思考题

假设student_course表上建有UPDATE触发器T1,该触发器的主要功能是限制mark的值最高为100。
(1)思考update student_course set mark=mark+5这样的语句在执行时,触发器T1是如何工作的,其在什么时候启动?会启动多少次?

就是当学生的成绩本来就是95分以上的时候就会执行触发器,
当更新到学生的成绩是95以上就跳到触发器的代码执行
替换了本来要执行的sql语句,有多少个学生成绩大于95触发器就执行多少次

(2)思考触发器T1能够使用check约束代替吗?对要修改的数据来讲两种方式的主要区别是什么?

主要区别:check约束中不能引用其他表中的列,而触发器可以;
check约束只是由逻辑符号连接的条件表达式,不能完成复杂的逻辑判断功能。

stuManage2数据库的备份,下载还原即可

发布了133 篇原创文章 · 获赞 37 · 访问量 4748

猜你喜欢

转载自blog.csdn.net/qq_43416157/article/details/104175938
今日推荐