数据库实验二
实验一已经完成了,虽然有点小插曲
我什么场面没见过 这场面我真没见过
事不宜迟,开始实验二
实验二要求:
1.设计与建立上课考勤表****Attend_???,能登记每个学生的考勤记录包括正常、迟到、旷课、请假。能统计以专业为单位的出勤类别并进行打分评价排序,如迟到、旷课、请假分别扣2,5,1分。可以考虑给一初始的分值,以免负值。
2.为major表与stud表增加sum_evaluation 数值字段,以记录根据考勤表Attend_???(Attendance)中出勤类别打分汇总的值。
3.建立个人考勤汇总表stud_attend与专业考勤表major_attend,表示每个学生或每个专业在某时间周期(起始日期,终止日期)正常、迟到、旷课、请假次数及考勤分值。
4.根据major表中的值与stud中的值,为考勤表Attend输入足够的样本值,要求每个专业都要有学生,有部分学生至少要有一周的每天5个单元(12,34,56,78,90,没有课的单元可以没有考勤记录)的考勤完整记录,其中正常、迟到、旷课、请假 可以用数字或字母符号表示。
5.建立触发器,当对考勤表Attend表进行相应插入、删除、修改时,对stud表的sum_evaluation 数值进行相应的数据更新。
6.建立过程,生成某专业某时段(起、止日期)的考勤汇总表major_attend中各字段值,并汇总相应专业,将考勤分值的汇总结果写入到major表中的sum_evaluation中。
首先,这次的实验和上次不一样,几个条件之间是有关系的,为了捋清楚,我先从二这种比较明确的做起
增加打分汇总值
代码如下
1 | alter table major_J314 drop column sum_evaluation; //删除字段,备用 |
这个地方注意了,oracle必须NOT NULL 在 Default后面,不然报错= =
建立考勤表
然后我们来捋一捋考勤表的字段与约束
- 统计学生,需要学生号SNO字段
- 考勤记录,需要记录ATTEND字段
- 需要统计以专业为单位,需要MajorNo字段
- 考勤需要记录时间,需要SDATE字段
- 四中把考勤一天分为5个单元,需要UNIT字段
建表如下:
1 | drop table attend_J314; |
初步建表就这样了
对了,发现一个问题,千万不要在最后一个字段后面加逗号,他会把 )
也当作字段读入,这个和css或者一些编程语言不一样了= =
建立个人考勤表和专业考勤表
个人/专业考勤表
- 个人的表需要SNO学号/专业号MajorNo
- 需要开始日期SDate
- 需要结束日期EDate
- 需要正常次数NCount
- 需要迟到次数LCount
- 需要旷课次数ABCount
- 需要成绩score
开始建表
1 | drop table stud_attend_J314; |
同理,初步建表就这样了
插入数据
又到了喜闻乐见的插(编)入(造)数(脑)据(洞)时间了,特别要求部分学生有一周一天五个单元的记录
代码如下
1 | insert into attend_J314 values('0902170314', '0', '02', to_date('20191028', 'YYYYMMDD'), '56'); |
在我准备插入的时候我发现一个问题,题设要求与实际需要都要是在stud和major表有的前提下的,所以我需要在attend表加上上面两个表的外键才对,添加如下重新建表
1 | drop table attend_J314; |
以此类推,stud_attend与major_attend两个表都需要加上SNO的外键约束
1 | constraint saj_sno_fk |
做到这一步,表,数据和关系都基本建立完成了,下一步就是触发器和过程了
先是触发器,要求在对attend表修改时,对stud_attend进行相应修改,那么问题来了,我们的stud_attend表还没有插入数据,那就先做数据插入吧= =
1 | select 'insert into stud_attend_J314 values ("'||SNO||'", to_date("20190901", "YYYYMMDD"), to_date("20200101", "YYYYMMDD"), 0, 0, 0, 100);' from stud_J314; |
在我把数据插入完后发现上一步的insert又走早了,需要先做触发器再做插入才比较好
attend表触发器我的打算是,先修改stud_attend_J314表再通过stud_attend_J314表的触发器触发stud_J314的修改
1 | create or replace trigger T_attend_J314 after insert or delete or update on attend_J314 for each row |
插入就不测试了,上面的都是例子,我们测试一下修改与删除
1 | delete from attend_J314 where SNO = '0904170105'; |
左调右调应该没什么问题了= =
下一步是建立一个过程,过程就是一个搜索并更新的过程
1 | create or replace procedure p_attend_J314 |
下面就是对过程的测试了
1 | exec p_attend_J314('02','20-10月-2019','03-11月-2019'); |