触发器实例

在student表中增加一列冗余列sum_grade,在sc表中作一触发器,当添加,删除,修改时,student表中sum_grade改变

create or replace trigger sc_ins_del_upd
after insert or delete or update of grade,sno on sc
for each row
  declare
  isum_grade number;
  begin
    if inserting then
      if :new.grade is null then--插入为空则不管
        return;
      else 
        select sum_grade into isum_grade from student where sno=:new.sno;
        if isum_grade is null then--原来总成绩为空则插入成绩为总成绩
          update student set sum_grade=:new.grade where sno=:new.sno;
        else--否则总成绩为现在成绩加插入成绩
          update student set sum_grade=sum_grade+:new.grade where sno=:new.sno;
        end if;
      end if;
    end if;
    --删除思路:因为行级触发器不能对变化表查询,所以我们先将总成绩减去删除成绩,如果删除后成绩为0,那么我们将会检查它是否拥有成绩为0的课
    if deleting then
       if :old.grade is null then
         return;
       else 
         update student set sum_grade = sum_grade-:old.grade where sno=:old.sno; select sum_grade into isum_grade from student where sno=:old.sno; if isum_grade=0 then pk1.isNull:=1; end if; end if; end if; if updating then null; end if; end;
create or replace trigger sc_del
after delete on sc
  begin
    if pk1.isNull=1 then--如果需要检查,我们可以设置一个语句级触发器,直接将成绩为0的学生总成绩行重置
      update student set sum_grade=(select sum(grade) from sc where sno=student.sno) where sum_grade=0;
      pk1.isNull:=0;
    end if;
  end;

这里,我们设置了一个全局变量的参数,这是我们将参数放在包中,只定义参数没有定义过程,这样就不用实现包体了,而且通过包名.参数名就可以调用全局变量了>.<就是这样

create or replace package pk1
is
       isNull number:= 0;
end pk1;

异常

create or replace trigger stu_ins_upd_del
before insert or delete or update of sage on student
for each row
  declare
  avg_grade number;
  begin
    if inserting then
      if :new.sage>30 and :new.sdept='RG' then
           raise_application_error(-20000,'RG系的学生年龄不能大于30');
      end if;
    end if;
    
    if updating then
      if :new.sage<:old.sage then
        raise_application_error(-20001,'年龄只能增不能加');
      end if;
    end if;
    
    if deleting then
      select avg(grade) into avg_grade from sc where sno=:old.sno;
      if avg_grade>60 then
        raise_application_error(-20002,'学生平均成绩大于60,不能删除');
      end if; 
      delete from sc where sno=:old.sno;
    end if; 
  end;

你可能感兴趣的:(oracle复习)