oracle-触发器练习
触发器课堂练习1
1、当向SC表插入数据时,修改(或添加)SC_NUMBER(包括学生学号和选课门数两列)
表格中的数据。
create or replace trigger tr_sc_AR_I
after insert on sc
for each row
begin
update sc_number set scnum=scnum+1where sno=:new.sno;
if sql%notfound then
insert into sc_number values(:new.sno,1);
end if;
end;
测试结果:
2、当删除SC表中数据时,修改(或添加)SC_NUMBER中的数据。
create or replace trigger tr_sc_AR_D
after delete on sc
for each row
begin
update sc_number set scnum=scnum-1where sno=:old.sno;
select scnum into pk_trigger.tr_scnum from sc_number where sno=:old.sno;
if(pk_trigger.tr_scnum=0) then
delete from sc_number where sno=:old.sno;
end if;
end;
测试结果:
3、当修改SC表中数据时,若修改的是学号,则对应修改SC_NUMBER表中的选课门数,否则打印“某某
(学生)的学生选课信息已经修改”信息。
create or replace trigger tr_sc_AR_U
after update on sc
for each row
begin
if(:old.sno = :new.sno) then
select sname into pk_trigger.tr_sname from student where sno=:new.sno;
dbms_output.put_line(pk_trigger.tr_sname||'的学生选课信息已经修改,由原课程'|| trim(:https://www.360docs.net/doc/3314935877.html,o)||'修改为新课程'||trim(:https://www.360docs.net/doc/3314935877.html,o));
end if;
if(:old.sno <> :new.sno) then
update sc_number set scnum=scnum+1where sno=:new.sno;
if sql%notfound then
insert into sc_number values(:new.sno,1);
end if;
update sc_number set scnum=scnum-1where sno=:old.sno;
select scnum into pk_trigger.tr_scnum from sc_number where sno=:old.sno;
if(pk_trigger.tr_scnum=0) then
delete from sc_number where sno=:old.sno;
end if;
end if;
end;
测试结果:
触发器课堂练习 2
1、修改STUDENT表数据时,限制不能修改学生的系别(不能修改CS系学生的系别)。create or replace trigger tr_student_BR_U1
before update of sdept on student
for each row
when (old.sdept='CS') --old前没有":"
begin
raise_application_error(-20001,'不能修改CS系学生的系别!');
end;
测试结果:
2、插入课程时,课程号以‘S’开头的课程的学分不能低于3分。
create or replace trigger tr_course_BR_I
before insert on course
for each row
when (new.credit<3and https://www.360docs.net/doc/3314935877.html,o like'S%')
begin
raise_application_error(-20002,'S开头的课程学分不能低于3分!'); end;
测试结果:
3、不能删除90分以上学生的选课信息。
create or replace trigger tr_sc_BR_D
before delete on sc
for each row
when (old.grade>90)
begin
raise_application_error(-20003,'不能删除90分以上学生的选课信息!'); end;
测试结果:
练习 1
1、插入Student表中数据时,CS系学生的年龄不能大于30岁。
create or replace trigger tr_student_BR_I
before insert on student
for each row
--when(new.sage>30 and new.sdept='CS')
begin
if(:new.sage>30and :new.sdept='CS') then
raise_application_error(-20004,'CS系学生的年龄不能大于30岁!');
end if;
end;
测试结果:
2、当修改Student表中的年龄字段时,使其只能增加,不能减少。
create or replace trigger tr_student_BR_U
before update of sage on student
for each row
when (new.sage begin raise_application_error(-20005,'年龄只能增加不能减少!'); end; 测试结果: 3、删除Student表中的学生信息时,判断在SC表中该学生的平均成绩是否高于60,若高于60,则不能删除,否则允许删除,同时删除SC表该学生对应的选课信息。 create or replace trigger tr_student_BR_D before delete on student for each row declare avg_score number; begin select avg(grade) into avg_score from sc where sc.sno =:old.sno; if(avg_score > 60) then raise_application_error(-20006,'不能删除平均分大于60的学生信息!'); end if; if(avg_score <= 60) then delete from sc where sc.sno=:old.sno; end if; end; 测试结果: 练习 2 在Student表中添加列:sum_Grade(总成绩),avg_grade(平均成绩)。 在SC表中作一触发器,当添加,删除或修改一行之后,将该学生在Student表中的总成绩和平均成绩相应改变。 create or replace package pk_trigger is tr_scnum smallint;--sc_number表中的当前选课数量 tr_sname student.sname%type; tr_cno https://www.360docs.net/doc/3314935877.html,o%type;--记录正在更新的课程号 tr_newsno sc.sno%type;--记录更新后的学生号 tr_oldsno sc.sno%type;--记录更新前的学生号 end pk_trigger; create or replace trigger tr_sc_BR_I_U_D before insert or update or delete on sc for each row begin pk_trigger.tr_newsno := :new.sno; pk_trigger.tr_oldsno := :old.sno; end; create or replace trigger tr_sc_AL_I_U_D after insert or update or delete on sc declare v_sum number; v_avg number; begin --更新变化之前的学生的总分和平均成绩 select sum(grade),avg(grade) into v_sum,v_avg from sc where sno=pk_trigger.tr_oldsno; update student set sum_grade=v_sum,avg_grade=v_avg where sno=pk_trigger.tr_oldsno; --更新变化之后的学生总分和平均分 select sum(grade),avg(grade) into v_sum,v_avg from sc where sno=pk_trigger.tr_newsno; update student set sum_grade=v_sum,avg_grade=v_avg where sno=pk_trigger.tr_newsno; end; 测试结果: 修改学号 删除 插入或修改(修改课程号时)选课信息时,若该课程的选课人数已满,则不允许操作,并抛出相应的错误提示。 create or replace package pk_trigger is tr_scnum smallint;--sc_number表中的当前选课数量 tr_sname student.sname%type; tr_cno https://www.360docs.net/doc/3314935877.html,o%type;--记录正在更新的课程号 tr_newsno sc.sno%type;--记录更新后的学生号 tr_oldsno sc.sno%type;--记录更新前的学生号 end pk_trigger; create or replace trigger tr_sc_BR_IU before insert or update on sc for each row begin pk_trigger.tr_cno:=:https://www.360docs.net/doc/3314935877.html,o; end; create or replace trigger tr_sc_AL_IU after insert or update on sc declare v_snumber smallint; v_scnt smallint; begin --查询课程最大选课人数 select snumber into v_snumber from course where o=pk_trigger.tr_cno; --查询当前选课人数 select count(sno) into v_scnt from sc where o=pk_trigger.tr_cno; --如果选课人数已满,则抛出相应错误提示 if(v_snumber < v_scnt) then raise_application_error(-20008,'课程'||trim(pk_trigger.tr_cno)||'选课人数已满!'); end if; end; 测试结果: