实验七 存储过程和触发器

版权声明:喜欢就点个赞吧,有啥疑问可以留言交流~ https://blog.csdn.net/m0_38015368/article/details/84986612

实验七 存储过程和触发器

一.实验目的:

1.掌握存储过程的创建及执行

2.掌握触发器的创建及测试

二.实验内容:(所有题写到实验报告中)

1 存储过程的创建及执行

1)

①在stuinfo数据库中创建一个存储过程p1,查询指定学号的学生的姓名和平均分,要求姓名和平均分使用返回参数。

②执行该存储过程查询学号为101的学生的姓名和平均分。

create proc p1 
@num char(5)
as
select student.sname, AVG(degree) as 平均分 
from score, student 
where  student.sno = @num and student.sno = score.sno group by student.sno, student.sname

exec p1 '103'
# 由于在后续实验中将学号为 '101' 学生删除了,此处及后续截图均为查询 '103'
--- 此答案错误,见下图后面的修改!


修改: 未经测试!题干要求返回结果,因此原答案不对,改为以下:

create proc p1 
@num char(5),
@name char(5) output,
@davg float output
as
select @name = student.sname, @davg = AVG(degree) from score, student 
where  student.sno = @num and student.sno = score.sno group by student.sno, student.sname

declare @name char(5)
declare @davg float

exec p1 '103', @name output, @davg output
print '姓名    平均分'
print @name + '  ' + cast(@davg as char(5))

2)

①在stuinfo数据库中创建存储过程P2,根据指定的学号和课程号判断成绩等级(A、B、C、D、E)(如果degree>=90则为A,依次类推,不及格为E)。

②执行该存储过程查看学号为101、课程号为3-105的成绩等级。

create proc p2
@sno char(5), @cno char(6)
as
select 成绩等级 = 
case
when degree >= 90 then 'A'
when degree >= 80 and degree < 90 then 'B'
when degree >= 70 and degree < 80 then 'C'
when degree >= 60 and degree < 70 then 'D'
else 'E'
end
from score where cno = @cno and sno = @sno 

exec p2 '103', '3-105'

3)

①在stuinfo数据库中创建存储过程P3,检查指定学号的学生是否有选课。有就输出其姓名、课程名和成绩,没有就输出“该生无选课”。

②执行该存储过程分别查看学号为101和888学生的选课情况。

create proc p3
@sno char(5)
as 
if (exists (select * from score where sno = @sno))
    select sname, cname, degree from course, student, score where student.sno = @sno and score.sno = student.sno and score.cno = course.cno 
else
    print '该生无选课'

exec p3 '103'
exec p3 '888'


4)

①在OrderManagement数据库中创建存储过程P4,查询指定客户号的订单中有多少种器件。

②执行该存储过程查看客户号是C0001的客户所订购的器件种类的数量。

use OrderManagement
create proc p4
@cusnum char(6)
as
select count(器件号) as 器件种类 from order_detail, order_list where order_list.客户号 = @cusnum and order_detail.订单号 = order_list.订单号

exec p4 'C10001'

5)

①在OrderManagement数据库中创建存储过程P5,查询指定年份的销售总额。

②执行该存储过程查看2001年的销售总额。要求执行完存储过程后按如下格式输出数据:

  2001年的销售总额:
  ----------------------------
  ******元
create proc p5
@year int
as
declare @total int
set @total = (select sum(单价 * 数量) from order_detail, order_list where year(order_list.订购日期) = @year and order_detail.订单号 =  order_list.订单号)
print cast(@year as varchar) + '年的销售总额:'
print '----------------'
print @total

exec p5 '2001'

6)

①在OrderManagement数据库中创建存储过程P6,修改指定订单号和器件号的单价。

②执行该存储过程将订单号为OR-01C、器件号为P1001的单价修改为1000。

create proc p6
@ordernum char(6), @machinenum char(5), @newprice int
as
update order_detail set 单价 = @newprice where 订单号 = @ordernum and 器件号 = @machinenum

exec p6 'OR-01C','P1001','1000'
select * from order_detial where 订单号 ='OR-01C' and  器件号 = 'P1001'

7)

①在OrderManagement数据库中创建存储过程P7,查询订单中至少订购了“CPU P4 1.4G”和“内存”这两种器件的订单号。

②执行该存储过程。

create proc p7
as
select a.订单号 from 
(select  订单号 from order_detail where 器件名 = '内存') as a,
(select  订单号 from order_detail where 器件名 = 'CPU P4 1.4G') as b
where a.订单号 = b.订单号

exec p7


2. 触发器的创建及测试

1)

①在student表上创建触发器t1,在用户插入、修改和删除记录时,都会自动显示表中的内容。

② 测试:对student表分别用insert、update和delete语句进行测试。

use stuinfo
create trigger t1
on student
after insert,update,delete
as
select * from student 

insert into student (sno, sname) values ('0242', 'zzz')
update student set ssex = '男' where sno = '0242'
delete from student where sno = '0242'

2)

①建立一个触发器t2,当向student表中插入数据时,如果姓名不重复则插入,如果出现姓名重复的情况,则提示错误(raiserror(‘姓名重复,不能插入’,16,1))并回滚该事务(即取消插入的行)。

② 测试:对student表分别用insert语句插入一条姓名重复的记录和姓名不重复的记录进行测试。

create trigger t2
on student
after insert
as
declare @sname char(10)
declare @num int
select @sname = sname from inserted
select @num = COUNT(*) from student where sname = @sname
if(@num != 1)
begin
raiserror('姓名重复,不能插入',16,1);
rollback tran;
end

insert into student (sno, sname) values ('0243', '李军')

3)

①建立一个触发器t3,当向student表中插入数据时,如果出现性别不正确的情况,不回滚该事务,只提示错误消息。

② 测试:对student表分别用insert语句插入一条性别正确的和性别不正确的记录进行测试。

create trigger t3
on student
after insert
as
declare @ssex char(2)
select @ssex = ssex from inserted
if(@ssex != '男' and @ssex != '女')
raiserror('Error: 性别不符合规定哦~',16,10)

insert into student (sno, sname, ssex) values ('04257', 'zzz', '5')

4)

①一个修改触发器t4,该触发器防止用户修改表student的学号。

② 测试:对student表分使用update语句修改学号进行测试。

create trigger t4
on student
after update
as
declare @sno_before char(5)
declare @sno_after char(5)
select @sno_before = sno from deleted
select @sno_after = sno from inserted
if(@sno_before !=  @sno_after)
begin
raiserror('学号不能更改',16,1);
rollback tran;
end

update student set sno = '103' where sno = '101'

5)

①建立一个触发器t5,将student表中所有修改时改前的记录及修改日期保存到ss表中作为历史记录。

② 测试: 使用命令查询student表中的信息,再使用命令将student表中的1031班改为1032班,然后使用命令查询ss中的记录检查触发器t2是否正确。

create trigger t5
on student
after update
as
declare @no char(5)
declare @name char(10)
declare @sex char(2)
declare @birthday datetime
declare @class char(10)
declare @now datetime
select @no = sno, @name = sname, @sex = ssex, @birthday = sbirthday, @class = sclass from deleted
set @now = GETDATE()
if OBJECT_ID(N'ss',N'U') is null
begin
create table ss(
sno char(5) not null,
sct datetime not null,
sname char(10),
ssex char(2),
sbirthday datetime,
sclass char(10),
primary key(sno, sct)
)
end
insert into ss values (@no, @now, @name, @sex, @birthday, @class)

update student set ssex = '男' where sno = '107'
select * from ss

6)

①创建触发器t6,当删除student表中的某个学生记录时,应该也同时删除score表中该生的选课记录。

②测试:在student表中添加一条学号为222的学生记录,在score表中添加该学号三条选课记录,然后删除学生表中的该学号的学生记录,检查score表中学号为222的记录是否还存在,从而测试该触发器是否正确。

create trigger t6
on student
after delete
as
declare @sno char(5)
select @sno = sno from deleted
delete from score where sno = @sno

insert into student (sno, sname) values ('222', 'sdust')
insert into score values ('222', '3-105', 100)
insert into score values ('222', '6-166', 100)
insert into score values ('222', '3-245', 100)
select * from score where sno = '222'  -- 察看
delete from student where sno = '222'
select * from score where sno = '222'  -- 察看


7)

①创建触发器t7,当修改student表中的某个学生学号时,同时也修改score表中该生的学号。

②测试:使用命令分别查询student表和score表中学号为的学生信息,再使用命令将student表中101的学号的改为999,然后使用命令再分别查询student表和score表中学号为101和的999的记录。

-- 执行这条的时候需要将  t4 禁用
disable trigger t4 on student -- 禁用

create trigger t7
on student
after update
as
declare @sno_before char(5)
declare @sno_after char(5)
select @sno_before = sno from deleted
select @sno_after = sno from inserted
update score set sno = @sno_after where sno = @sno_before

update student set sno = '999' where sno = '101'
select * from student where sno = '101'
select * from score where sno = '101'
select * from student where sno = '999'
select * from score where sno = '999'

猜你喜欢

转载自blog.csdn.net/m0_38015368/article/details/84986612