SQL触发器和视图的使用
相关题目:
😪 给定表:学生表(学号,姓名,出生年份,电话)、选课表(学号,课号,成绩)、课程表(课号,课程名,学分)
1. 学分必须为1~8之间的数,不能为空。要求用触发器实现
2. 定义视图,统计某课程成绩最高的前三名学生信息。字段为学号,姓名,课号,课名,成绩
3. 记录选课表的更新、删除和插入元组的时间和用户及相应的值,使用触发器实现
4. 定义视图,显示学生基本信息,字段为:学号,姓名,年龄,电话
数据表结构:
1. 选课表:
学号:采用定长串表示,即char型
课号:采用定长串表示,即char型
成绩:采用短整数表示,即smallint型
create table sel_course_tb
(
Snum char(10),
Cnum char(4),
Ccredit smallint,
constraint course_tb_pk PRIMARY KEY(Snum,Cnum),
constraint sel_course_tb_1 foreign KEY(Snum) references student_tb(Snum),
constraint sel_course_tb_2 foreign KEY(Cnum) references course_tb(Cnum)
);
2. 学生表:
学号:采用定长串表示,即char型
姓名:采用可变长串表示,即varchar型
出生年月:采用日期表示,即date型
电话:采用定长串描述,即char型
create table student_tb
(
Snum char(10),
Sname varchar(20),
Sdate date,
Sphone char(11),
constraint student_tb_pk PRIMARY KEY(Snum),
constraint student_tb_uk UNIQUE(Snum)
);
3. 课程表:
课号:采用定长串表示,即char型
课程名:采用可变长串表示,即varchar型
学分:采用短整数表示,即smallint型
create table course_tb
(
Cnum char(4),
Cname varchar(30),
Ccredit smallint,
constraint course_tb_pk PRIMARY KEY(Cnum),
constraint course_tb_uk UNIQUE(Cnum)
);
插入数据:
-
向学生表插入数据:
insert into student_tb values('0201121514', '张三','2002-01-01','15624626879');
-
向课程表插入数据:
insert into course_tb values('01','数据通信原理',5);
-
向选课表插入数据:
insert into sel_course_tb values('0201121514','01',80);
题目一:学分必须为1~8之间的数,不能为空。要求用触发器实现
基本思路:判断学分是否不在1~8,若不在,抛出一个异常
delimiter
create trigger is_credit_right before insert on course_tb
for each row
begin
if new.Ccredit > 8 or new.Ccredit < 0 or new.Ccredit is null then
SIGNAL SQLSTATE '97875' SET MESSAGE_TEXT = "学分必须为1~8之间的数,不能为空";
end if;
end;
插入一个数据检查一下触发器是否正常工作
insert into course_tb
values('10','线性代数',null);
发现一个异常被抛出,数据没有被插入表
题目二:定义视图,统计某课程成绩最高的前三名学生信息。字段为学号,姓名,课号,课名,成绩
这里统计课程号为 01 的成绩最高的前三名学生信息
create view view_q3_1 as
select student_tb.Snum,student_tb.Sname,course_tb.Cnum,course_tb.Cname,sel_course_tb.Ccredit
from student_tb,course_tb,sel_course_tb
where sel_course_tb.Cnum = '01' and
course_tb.Cnum = sel_course_tb.Cnum and
student_tb.Snum = sel_course_tb.Snum
order by sel_course_tb.Ccredit desc limit 3;
题目三:记录选课表的更新、删除和插入元组的时间和用户及相应的值,使用触发器实现
先建一个表,统计对某个数据的操作
create table uid_time_tb
(
op_Snum char(10) not null,
op_Cnum char(4) not null,
op_user varchar(120),
insert_time datetime,
update_time datetime,
constraint uid_pk primary key(op_Snum,op_Cnum)
)
建一个插入数据的触发器,使用 after 触发器
current_user
获取系统用户,current_timestamp
获取系统时间
delimiter
create trigger insert_time after
insert on sel_course_tb
for each row
begin
insert into uid_time_tb
values(new.Snum,new.Cnum,current_user,CURRENT_TIMESTAMP,null);
end;
drop trigger insert_time;
最后检查一下执行结果
insert into sel_course_tb
values('0201121521','09',70);
select*from uid_time_tb;
记录更新、删除操作的触发器道理和insert
触发器一样,直接粘贴代码
delimiter
create trigger update_time after
update on sel_course_tb
for each row
begin
update uid_time_tb set update_time = CURRENT_TIMESTAMP
where uid_time_tb.op_Snum = new.Snum and uid_time_tb.op_Cnum = new.Cnum;
end;
delimiter
create trigger delete_time before
delete on sel_course_tb
for each row
begin
update uid_time_tb set delete_time = CURRENT_TIMESTAMP
where uid_time_tb.op_Snum = old.Snum and uid_time_tb.op_Cnum = old.Cnum;
end;
drop trigger delete_time;
题目四:定义视图,显示学生基本信息,字段为:学号,姓名,年龄,电话。
建立视图很简单,直接 create view
即可,计算年龄的话,用系统时间减去学生的生日即可,注意要用year
函数获得年份!直接 paste 代码
create view view_all(学号,姓名,年龄,电话) as
select
student_tb.Snum,
student_tb.Sname,
year(current_date())-year(student_tb.Sdate),
student_tb.Sphone
from student_tb;
select *from view_all;
一点心得:
上述代码都是在MySQL 8上跑的,基本没什么问题,图形界面是用MySQL自带的MySQl workbench CE
这些题目是老师在讨论课上布置的,因为刚刚接触SQL,不了解SQL语句性能的差异,一些操作的性能可能很差劲哎🤣
约束主要被用于强制数据的完整性,约束能提供比触发器更好的性能。
约束只能对其所在表中的数据,触发器可以从任何表上的数据进行检查。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现