《数据库概论》实验报告
《数据库系统概论》
实验报告书
专业班级
学
号
姓
名
指导教师
实验一:数据定义语言
[ 实验日期
1 ]
2011 年
10 月
22
日
[ 实验目的
] ]
熟悉 Oracle 上机环境及 Oracle 客户端的配置;熟练掌握和使用 DDL 语言,建立、修改和删除数据库表、主键、外键约束关系和索引。
[ 实验内容
] ]
1 1 .
L SQL 数据定义语句:
例 1-1:
(建立数据库表)
建立教学数据库的四个数据库表,其中 Student 表中不包含 SSEX(C,2) 字段,Sname 字段为 Sname(C,8)且可为空。
create table Student (Sno char(5),
Sname char(8),
Sdept char(2) not null unique,
Sclass char(2) not null unique,
Sage number(2),
constraint Sno_pk PRIMARY KEY(Sno)) ;
create table Course (Cno char(3) PRIMARY KEY,
Cname char(16),
Ctime number(3)) ;
create table SC (Sno char(5),
Cno char(2),
Grade numble(3),
constraint SC_pk PRIMARY KEY(Sno,Cno),
constraint Sno_fk foreign KEY(Sno) references Student(sno), constraint Sno_pk PRIMARY KEY(Sno)) ;)
create table Teach (Tname char(8),
Tsex char(2),
Cno char(3),
Tdate date,
Tdept char(2),
constraint Teach_pk PRIMARY KEY(Tname,Cno,Tdept),
constraint Cno_fk foreign KEY(Cno) references Course(Cno));
create table Score (Sno char(5),
Cno char(3),
Score number(5,2),
constraint Score_pk PRIMARY KEY(Sno,Cno),
constraint Sno_fk foreign KEY(Sno) references Student(Sno),
constraint Cno_cfk foreign KEY(Cno) references Course(Cno));
例 1-2:
(修改数据库表)
在 Student 表中增加 SEX(C,2) 字段。
alter table Student add Sex char(2) ;
例 1-3:
(修改列名)
将 Student 表中列名 SEX 修改为 SSEX。
alter table Student rename column Sex to Ssex ;
例 1-4:
(修改数据库表)
将 Student 表中把 Sname 字段修改为 Sname(C,10)且为非空。
alter table student modify(sname not null);
例 1-5:
(建立索引)
为 Score 表按课程号升序、分数降序建立索引,索引名为 SC_GRADE。
create unique index SC_GRADE on Score(Cno asc,Score desc) ;
例 1-6:
(删除索引)
删除索引 SC_GRADE。drop index SC_GRADE;
例 1-7:
(建立数据库表)
建立数据库表 S1(SNO,SNAME,SD,SA),其字段类型定义与 Student 表中的相应字段(SNO,SNAME,SDEPT,SAGE)的数据类型定义相同。
create table S1
(Sno char(5),
Sname char(10),
Sd char(2),
Sage number(2));
例 1-8:
(修改数据库表)
删除成绩表 Score 的参照完整性约束关系。
alter table score drop constraint cno_cfk;
例 1-9:
(修改数据库表)
添加成绩表 Score 的参照完整性约束关系。
alter table score add constraint Sno_fk foreign KEY(sno) references Student(Sno); alter table score add constraint cno_cfk foreign KEY(cno) references Course(cno);
例 1-10:
(修改数据库表名)
将数据库表 S1 改名为 Student_Temp。
rename s1 to Student_Temp;
[ 实验要求
] ]
①
熟悉 Oracle 上机环境,掌握 Oracle 客户端的配置; ②
建立数据库表,修改数据库表结构,建立、删除索引;
[ 实验方法
] ]
①
按照附录中的操作步骤进行客户端的配置;
②
将实验需求用 SQL 语句表示;
③
执行 SQL 语句;
④
查看执行结果,如果结果不正确,进行修改,直到正确为止。
[ [
实验总结
] ]
经过这次实验使我对 sql 语句对表的创建,修改和删除等操作更加熟练。
实验二:数据操纵语言
[ 实验日期
]
2011
年
10
月
22
日
[ 实验目的
] ]
在实验一的基础上,熟练掌握和使用 DML 语言,对数据进行增加、修改和删除操作。
[ 实验内容
] ]
2 2 .
L SQL 数据操纵语句:
例 2-1:(插入数据)
按前面各表中的数据分别插入到教学数据库的四个数据库表中。
insert into Student values("96001","马小燕","cs","01",21,"女"); insert into Student values("96002","黎明","cs","01",18,"男"); insert into Student values("96003","刘东明","ma","01",18,"男"); insert into Student values("96004","赵志勇","is","02",20,"男"); insert into Student values("97001","马蓉","ma","02",19,"女"); insert into Student values("97002","李成功","cs","01",20,"男"); insert into Student values("97003","黎明","is","03",19,"女"); insert into Student values("97004","李丽","cs","02",19,"女"); insert into Student values("96005","司马志明","cs","02",18,"男");
insert into course values("001","数学分析",144);
insert into course values("002","普通物理",144);
insert into course values("003","微机原理",72);
insert into course values("004","数据结构",72);
insert into course values("005","操作系统",64);
insert into course values("006","数据库原理",64);
insert into course values("007","DB_Design",48); insert into course values("008","程序设计",56);
insert into teach values("王成刚","男","004","05-9 月-1999","cs"); insert into teach values("李正科","男","003","05-9 月-1999","cs"); insert into teach values("严敏","女","001","05-9 月-1999","ma"); insert into teach values("赵高","男","004","05-9 月-1999","is"); insert into teach values("李正科","男","003","23-2 月-2000","ma"); insert into teach values("刘玉兰","女","006","23-2 月-2000","cs"); insert into teach values("王成刚","男","004","23-2 月-2000","is"); insert into teach values("马悦","女","008","06-9 月-2000","cs"); insert into teach values("王成刚","男","007","05-9 月-1999","cs");
insert into score values("96001","001",77.5); insert into score values("96001","003",89); insert into score values("96001","004",86); insert into score values("96001","005",82); insert into score values("96002","001",88); insert into score values("96002","003",92.5); insert into score values("96002","006",90); insert into score values("96005","004",92); insert into score values("96005","005",90); insert into score values("96005","006",89); insert into score values("96005","007",76); insert into score values("96003","001",69); insert into score values("97001","001",96); insert into score values("97001","008",95);
insert into score values("96004","001",87); insert into score values("96003","003",91); insert into score values("97002","003",91); insert into score(sno,cno) values("97002","004"); insert into score values("97002","006",92); insert into score values("97004","005",90); insert into score values("97004","006",85); insert into score values("97004","008",75); insert into score values("97003","001",59); insert into score values("97003","003",58);
例 2-2:(多行插入)
将表 Student 中在计算机系(‘CS’)的学生数据插入到表 Student_Temp 中。
insert into Student_Temp values("96001","马小燕","cs",21); insert into Student_Temp values("96002","黎明","cs",18); insert into Student_Temp values("97002","李成功","cs",20); insert into Student_Temp values("97004","李丽","cs",19); insert into Student_Temp values("96005","司马志明","cs",18); 例 2-3:(利用查询来实现表的定义与数据插入)
求每一个学生的平均成绩,把结果存入数据库表Student_Gr 中。
create table Student_Gr (sno char(5)not null,
avgscore number(5,2)); insert into Student_Gr(sno,avgscore) select sno,avg(score) from score group by sno; 例 2-4:
(修改数据)
将 Student_Temp 表中所有学生的年龄加 2。
update Student_Temp set sage =sage+2; 例 2-5:
(修改数据)
将 Course 表中‘程序设计’课时数修改成与‘数据结构’的课时数相同。
update course set ctime=(select ctime from course where cname="数据结构"where cname="程序设计"; 例 2-6:
(插入数据)
向 Score 表中插入数据(‘98001’, ‘001’, 95),根据返回信息解释其原因。
insert into score values("98001","001",95); 因为引入了外键 sno,来源于表 Student,而在 Student中没有 98001 这个学号,故无法插入。
例 2-7:
(插入数据)
向 Score 表中插入数据(‘97001’, ‘010’, 80),根据返回信息解释其原因。
insert into score values("97001","010",80); 因为引入了外键 cno,来源于表 course,而在 course中没有 010 这个课程号,故无法插入。
例 2-8:
(删除数据)
删除 Student 表中学号为‘96001’的学生信息,根据返回信息解释其原因。
delete from student where sno="96001";违反完整性约束条件,已找到子记录日志 例 2-9:
(删除数据)
删除 Course 表中课程号为‘003’ 的课程信息,根据返回信息解释其原因。
delete from course where cno="003"; 违反完整性约束条件,已找到子记录日志
例 2-10:
(删除数据)
删除学生表 Student_Temp 中学号以 96 打头的学生信息。
delete from Student_Temp where sno like"96___"; ( 此 操作 后 ,注意用 K ROLLBACK 回退可能更新的 数据)
例 2-11:
(删除数据)
删除数据库表 Student_Temp 中所有学生的数据。
delete from student_temp;
例 2-12:(删除表)
删除数据库表 Student_Temp 和 Student_Gr。
drop table student_temp; drop table student_gr; [ 实验要求
] ]
对数据库表进行插入、修改和删除数据的操作。
[ 实验方法
] ]
①
按照附录中的操作步骤进行客户端的配置;
②
将实验需求用 SQL 语句表示;
③
执行 SQL 语句;
④
查看执行结果,如果结果不正确,进行修改,直到正确为止。
[ [
实验总结
] ]
通过这次实验使我对插入数据更加熟练,对约束条件的作用也有了更深的理解。
实验三:数据查询语言
[ 实验日期
]
2 011
年
10
月
22
日
[ 实验目的
] ]
体会 SQL 语言数据查询功能的丰富和复杂。
[ 实验内容
] ] 3 3 .
L SQL 数据查询语句:
例 3-1:
(选择表中的若干列)
求全体学生的学号、姓名、性别和年龄。
select sno,sname,ssex,sage from student;
例 3-2:
(不选择重复行)
求选修了课程的学生学号。
select distinct sno from score;
例 3-3:
(选择表中的所有列)
求全体学生的详细信息。
select *from student;
例 3-4:
(使用表达式)
求全体学生的学号、姓名和出生年份。
select sno,sname,2011-sage as "birth" from student;
例 3-5:
(使用列的别名)
求学生的学号和出生年份,显示时使用别名“学号”和“出生年份”。
select sno as "学号",2011-sage as"出生年份" from student; 例 3-6:
(比较大小条件)
求年龄大于 19 岁的学生的姓名和年龄。
select sname,sage from student where sage>19;
例 3-7:
(比较大小条件)
求计算机系或信息系年龄大于 18 岁的学生的姓名、系和年龄。
select sname,sdept,sage from student where sage>19 and sdept in ("cs","is");
例 3-8:
(确定范围条件)
求年龄在 19 岁与 22 岁(含 20 岁和 22 岁)之间的学生的学号和年龄。
select sno,sage from student where sage between 19 and 22; 例 3-9:
(确定范围条件)
求年龄不在 19 岁与 22 岁之间的学生的学号和年龄。
select sno,sage from student where sage not between 19 and 22; 例 3-10:(确定集合条件)
求在下列各系的学生信息:数学系、计算机系。
select *from student where sdept in ("ma","cs");
例 3-11:(确定集合条件)
求不是数学系、计算机系的学生信息。
select *from student where sdept not in ("ma","cs");
例 3-12:(匹配查询)
求姓名是以“李”打头的学生。
select sname from student where sname like "李%";
例 3-13:(匹配查询)
求姓名中含有“志”的学生。
select sname from student where sname like "%志%";
例 3-14:(匹配查询)
求姓名长度至少是三个汉字且倒数第三个汉字必须是“马”的学生。
select sname from student where sname like "%马__"; 例 3-15:(匹配查询)
求选修课程 001 或 003,成绩在 80 至 90 之间,学号为 96xxx 的学生的学号、课程号和成绩。select sno,cno,score from score where cno in ("001","003") and score between 80 and 90 and sno like"96___";
例 3-16:(匹配查询)
求课程名中包含 ’_’ 字符的课程号、课程名和学时数。
select cno,cname,ctime from course where Cname like"%/_%"escape"/";
例 3-17:(涉及空值查询)
求缺少学习成绩的学生的学号和课程号。
select sno,cno from score where score is null;
例 3-18:(控制行的显示顺序)
求选修 003 课程或 004 课程的学生的学号、课程号和分数,要求按课程号升序、分数降序的顺序显示结果。
select sno,cno,score from score where cno in ("003","004") order by cno asc,score desc;
例 3-19:(组函数)
求学生总人数。select count(sno) from student;
例 3-20:(组函数)
求选修了课程的学生人数。select count(distinct sno) from score;
例 3-21:(组函数)
求计算机系学生的平均年龄。select avg(sage) from student where sdept="cs";
例 3-22 :
( 组 函 数 )
求 选 修 了 课 程 001 的 最 高 、 最 低 与 平 均 成 绩 。
select max(score),min(score),avg(score)from score where cno="001"; 例 3-23:(分组查询)
求各门课程的平均成绩与总成绩。
select avg(score),sum(score)from score group by cno;
例 3-24:(分组查询)
求各系、各班级的人数和平均年龄。
select sdept,sclass,count(sno),avg(sage)from student group by sdept,sclass;
例 3-25:(分组查询)
输入以下查询语句并执行,观察出现的其结果并分析其原因。
SELECT SNAME,SDEPT,COUNT(*)FROM STUDENT WHERE SDEPT=’CS’ GROUP BY SDEPT;
例 3-26:(分组查询)
分析以下语句为什么会出现错误。并给出正确的查询语句。
SELECT SAGE FROM STUDENT GROUP BY SNO; 不是 group by 表达式;SELECT SAGE FROM STUDENT order by SNO;
例 3-27:(分组查询)
求学生人数不足 3 人的系及其相应的学生数。
select sdept,count(sno) from student group by sdept having count(sno)<3;
例 3-28:(分组查询)
求各系中除 01 班之外的各班的学生人数。
select sdept,sclass,count(sno) from student where sclass<>"01" group by sdept,sclass ;
例 3-29:(涉及空值的查询)
分别观察各组函数、行的显示顺序以及分组查询与空值的关系。
例 3-30:(连接查询)
求选修了课程 001 且成绩在 70 分以下或成绩在 90 分以上的学生的姓名、课程名称和成绩。
select sname,cname,score from student,course,score
where
student.sno=score.sno
and course.cno=score.cno
and score.cno="001"
and score.score not between 70 and 90;
例 3-31:(连接查询与表的别名)
求选修了课程的学生的学生姓名、课程号和成绩。
select sname,cno,score from student,score where student.sno=score.sno;
例 3-32:(自身连接查询)
求年龄大于 ’李丽’ 的所有学生的姓名、系和年龄。
select X.sname,X.sdept,X.sage from student X,student Y where x.sage>y.sage and y.sname="李丽";
例 3-33:(外部连接查询)
求选修了课程 002 或 003 的学生的学号、课程号、课程名和成绩,要求必须将 002 和 003 课程的相关信息显示出来。
select course.cno,course.cname,course.ctime,score.sno,score.score from course,score
where score.cno in("002","003");
例 3-34:(子查询)
求与 ‘黎明’ 年龄相同的学生的姓名和系。
select sname,sdept from student where sname<>"黎明" and sage in(select sage from student where sname="黎明");
例 3-35:(子查询)
求选修了课程名为 ’数据结构’ 的学生的学号和姓名。
select sname,student.sno from student,course,score where student.sno=score.sno
and course.cno=score.cno and course.cname="数据结构";
例 3-36:(子查询 ANY)
求比数学系中某一学生年龄大的学生的姓名和系。
select sname,sdept from student
where sage>any(select sage from student where sdept="ma")
and sdept<>"ma";
例 3-37:(子查询 ALL)
求比数学系中全体学生年龄大的学生的姓名和系。
select sname,sdept from student
where sage>all(select sage from student where sdept="ma")
and sdept<>"ma";
例 3-38:(子查询 EXISTS)
求选修了课程 004 的学生的姓名和系。
select sname,sdept from student where exists
(select * from score where sno=student.sno
and cno="004"); 例 3-39:(返回多列的子查询)
求与 ‘李丽’ 同系且同龄的学生的姓名和系。
select sname,sdept from student where sdept=(
select sdept from student where sname="李丽")
and sage=(select sage from student where sname="李丽");
例 3-40:(多个子查询)
求与 ‘‘黎明’ 同系,且年龄大于 ‘李丽’ 的学生的信息。
select sdept from student where sname="黎明")
and sage>(select sage from student where sname="李丽")
and sname<>"李丽" and sname<>"黎明";
例 3-41:(子查询中使用表连接)
求数学系中年龄相同的学生的姓名和年龄。
select sname,sage from student x where x.sdept="ma" and sage in(select sage from student
y where y.sdept="ma" and x.sno!=y.sno);
例 3-42:(连接或嵌套查询)
检索至少选修王成刚老师所授课程中一门课程的女学生姓名。
select sname from student where ssex="女" and sno in(select sno from score,teach where
score.cno=teach.cno and teach.tname="王成刚");
例 3-43:(嵌套与分组查询)
检索选修某课程的学生人数多于 3 人的教师姓名。
select tname from Teach x where count(select score.cno from teach y,score
where y.cno=score.cno and y.tname=x.tname)>3;
例 3-44:(集合查询)
列出所有教师和同学的姓名和性别。
select distinct sname,ssex,tname,tsex from student s1, teach s2 where s1.sdept=s2.tdept;
例 3-45:(相关子查询)
求未选修课程 004 的学生的姓名。
select sname from student where
exists(select * from score where cno<>"004");
例 3-46:(相关子查询)
求选修了全部课程的学生的姓名。
select sname from student
where
not exists (select * from course
where not exists
(select * from score
where sno=student.sno
and cno=course.cno)); 例 3-47:(相关子查询)
求至少选修了学生 ‘96002’ 所选修的全部课程的学生的学号。
select distinct sno from score s1
where not exists
( select * from
score s2
where s2.sno="96002"
and not exists
( select * from score s3
where sno=s1.sno
and cno=s2.cno))and sno!="96002";
例 3-48:(相关子查询)
求成绩比所选修课程平均成绩高的学生的学号、课程号、和成绩。
select sno,cno,score from score s1
where not exists (select
s2.cno,avg(s2.score) from score s2 group by cno having s1.score<avg(s2.score));
例 3-49:(相关子查询)
查询被一个以上的学生选修的课程号。
select cno,count(cno) from score group by cno having count(cno)>1; 例 3-50:(相关子查询)
查询所有未选课程的学生姓名和所在系。
select sname from student where sno not in (select sno from score where cno="004");
[ 实验要求
] ]
对数据库表进行各种查询操作。
[ 实验方法
] ]
①
将实验需求用 SQL 语句表示;
②
执行 SQL 语句;
③
查看执行结果,如果结果不正确,进行修改,直到正确为止。
[ [
实验总结
] ]
这次实验使我对 SQL 语句查询方面得到了很多的锻炼,很多我不熟的,不会弄的查询这次通过慢慢摸索总算知道了查询方法。
实验四:视图、授权控制与事务处理
[ 实验日期
]
2011
年
10
月
22 日
[ 实验目的
] ]
通过实验进一步理解视图的建立和更新、数据库的权限管理和事务处理功能。
[ 实验内容
] ]
4 4 .
L SQL 视图 的定义与操纵 :
例 4-1:
(建立视图)
建立计算机系的学生的视图 STUDENT_CS。
create view student_cs with check option;
例 4-2:
(建立视图)
建立由学号和平均成绩两个字段的视图 STUDENT_GR。
create view student_gr(sno,avg(score));
例 4-3:
(视图查询)
利用视图 STUDENT_CS,求年龄大于 19 岁的学生的全部信息。
select *from student_cs where sage>19; 例 4-4:
(视图查询)
利用视图 STUDENT_GR,求平均成绩为 88 分以上的学生的学号和平均成绩。
select sno,avg(score) as "平均成绩"from student_gr where avg(score)>88; 例 4-5:
(视图更新)
利用视图 STUDENT_CS,增加学生( ‘96006’,‘张然’,‘CS’,‘02’,‘男’,19 )。
insert into student_cs values("96006","张然","cs","02","男",19); 例 4-6:
(视图更新)
利用视图 STUDENT_CS,将学生年龄增加 1 岁。观察其运行结果并分析原因。
update student_cs set sage=sage+1; 例 4-7:
(视图更新)
利用视图 STUDENT_GR,将平均成绩增加 2 分。观察其运行结果并分析原因。
update student_gr set avg(score)=avg(score)+2; 例 4-8:
(视图更新)
删除视图 STUDENT_CS 中学号为 ‘96006’ 的学生的全部数据。
delete from student_cs where sno="96006"; 例 4-9:
(视图更新)
删除视图 STUDENT_GR 的全部数据。
delete student_gr;
例 4-10:(删除视图)
删除视图 STUDENT_CS 和 STUDENT_GR。
drop view student_cs; drop view student_gr; 5 5 .
L SQL 数据控制语句:
例 5-1:
(授权)
给左右邻近同学(用户)授予在表 Student 上的 SELECT 权限,并使这两个用户具有给其他用户授予相同权限的权限。
grant select on student to u74003,u74024 with grant option;
例 5-2:
(授权)
给邻近同学(用户)授予 Teach 表上的所有权限。
grant all on teach to u74003;
例 5-3:
(授权)
给所有用户授予 Score 表上的 SELECT 权限。
grant select on score to public; 例 5-4:
(授权验证)
观察左右邻近同学查询你所授权的表中的内容。
例 5-5:
(收回授权)
收回上面例子中的所有授予的权限。
revoke all privileges from public; revoke select on student from u74003,u74024; revoke all on teach from u74003; revoke select on score from public; 6 6 .
L SQL 事务处理:
例 6-1:
(事务回退)
将课程名称表中的 ‘程序设计’ 课程学时数修改为 80、‘微机原理’ 课程学时数修改为 70 学时,查询全部课程的总学时数后,取消所有修改(ROLLBACK)。再次查询全部课程的总学时数。注意比较分析两次查询的结果。
例 6-2:
(事务提交)
将课程名称表中的 ‘程序设计’ 课程学时数修改为 80、‘微机原理’ 课程学时数修改为 70 学时,查询全部课程的总学时数后,确认所有修改(COMMIT)。再次查询全部课程的总学时数。注意比较分析两次查询的结果。
6-1 图
6-2 图
[ 实验要求
] ]
① 建立视图,视图查询,视图更新; ② 给某一或全部用户授权和收回授权; ③ 事务回退,事务提交。
[ 实验方法
] ]
①
将实验需求用 SQL 语句表示;
②
执行 SQL 语句;
③
查看执行结果,如果结果不正确,进行修改,直到正确为止。
[ [
实验总结
] ]
通过实验我加深了对视图的理解,并且懂得了如何授权,还知道了事务回退和提交语句的作用。
实验五:e Oracle 存储过程与触发器
[ 实验日期
]
2010
年
10
月
22
日
[ 实验目的
] ]
通过实验进一步理解和掌握 Oracle 数据库的存储过程和触发器。
[ 实验内容
] ]
4 4 .
存储过程与触发器 :
例 7-1:
(存储过程) 创建一个显示学生总人数的存储过程。
set serveroutput on create or replace
procedure student_cnt
as
a number;
begin
select count(sno) into a from student;
dbms_output.put_line("学生总人数:");
dbms_output.put_line(a);
end; 例 7-2:
(存储过程) 创建显示学生信息的存储过程 STUDENT_LIST,并引用 STU_COUNT 存储过程。
create or replace procedure student_list as
begin
student_cnt;
end; 例 7-3:
(存储过程) 创建一个显示学生平均成绩的存储过程。
set serveroutput on
create or replace procedure stu_avg(
p1 in student.sno%type)
as a number;
begin
select avg(score) into a from score where sno=p1 group by(sno);
dbms_output.put_line(a);
end; 例 7-4:
(存储过程) 创建显示所有学生平均成绩的存储过程。
set serveroutput on create or replace procedure all_avg as
cursor stu_avg is select sno,avg(score) as a from score
group by(sno); data stu_avg%rowtype; begin
open stu_avg; loop fetch stu_avg into data; exit when stu_avg%notfound; dbms_output.put_line(data.sno||"
"||data.a);
end loop; close stu_avg; end; 例 7-5:
(修改数据库表) 在 Student 表中增加 SAVG(N,6,2) 字段。
alter table student add savg number(6,2);; 例 7-6:
(存储过程) 创建存储过程,计算每个学生的平均成绩保存到学生表 SAVG 字段中。
set serveroutput on
create or replace procedure cal_avg as
cursor c_avg is select sno,avg(score) as a from score
group by(sno);
data c_avg%rowtype;
begin
open c_avg;
loop
fetch c_avg into data;
exit when c_avg%notfound;
update student set savg=data.a
where sno=data.sno;
end loop;
close c_avg;
end; 例 7-7:
(触发器) 当更新学生成绩表 SCORE 中的学生成绩时,自动计算该学生的平均成绩保存到学生表 SAVG 字段中。
set serveroutput on
create or replace trigger sc_avg before insert or update on score
referencing new as new old as old
for each row
declare
pscore number;
n number;
news number;
begin
select sum(score) into pscore from score where sno=:new.sno;
select count(*) into n from score where sno=:new.sno;
update student set savg=(pscore+:new.score)/(n+1) where sno=:new.sno;
end; 例 7-8:
(触发器) 创建包含插入、删除、修改多种触发事件的触发器 DML_LOG,对 SCORE 表的操作进行记录。用 INSERTING、DELETING、UPDATING 谓词来区别不同的 DML 操作。
先创建事件记录表 LOGS,该表用来对操作进行记录。该表的字段含义解释如下:
LOG_ID:操作记录的编号,数值型,它是该表的主键,自动增 1,可由序列自动生成。
LOG_TABLE:进行操作的表名,字符型,非空,该表设计成可以由多个触发器共享使用。比如我们可以为 Student 表创建类似的触发器,同样将操作记录到该表。
LOG_DML:操作的动作,即 INSERT、DELETE 或 UPDATE 三种之一。
LOG_KEY_ID:操作时表的主键值,数值型。之所以记录表的主键,是因为主键是表的记录的惟一标识,可以识别是对哪一条记录进行了操作。对于 Score 表,主键是由 SNO_CNO 构成。
LOG_DATE:操作的日期,日期型,取当前的系统时间。
LOG_USER:操作者,字符型,取当时的操作者账户名。比如登录 SCOTT 账户进行操作,在该字段中,记录账户名为 SCOTT。
[ 实验要求
] ]
① 创建、调试和修改、调用和执行 Oracle 存储过程; ② 创建、调试和修改、测试 Oracle 触发器。
[ 实验方法
] ]
①
将实验需求用 SQL 语句表示;
②
执行 SQL 语句;
③
查看执行结果,如果结果不正确,进行修改,直到正确为止。
[ [
实验总结
] ]
这次实验使我加深了对触发器的认识。开始编写触发器时觉得很困难,都不知道怎么显示,而且发现“/”符号通过复制弄到 SQL plus 中时不能用,必须自己输进去。
上一篇:古典密码实验报告
下一篇:51单片机流水灯实验报告