文章目录

    • 1. 触发器概述.
    • 2. 临时表-:new和:old.
    • 3. 案例数据脚本
    • 4. 触发器语法
      • 案例1:后触发-delete操作.
      • 案例2:前触发insert&后触发delete&后触发&update.
      • 案例3:多表连删.
    • 触发器+序列=标识列.
      • 示例:实现标识列功能

1. 触发器概述.

  • 触发器的本质是一个存储过程,顾名思义,发生特定事件时Oracle才会执行触发器中的代码(和java-里面的监听器有点相似);
  • 特定事件:是执行更新的DML和DDL语句;
  • 触发器不能显式(手动)被调用;

  • 触发器的组成部分
  1. 触发器语句(事件):定义激活触发器的 DML 事件和 DDL 事件;
  2. 触发器限制(when):执行触发器的条件,该条件必须为真才能激活触发器;
  3. 触发器操作(主体):就是触发器被触发以后具体想表达的事件,在 begin 和 end 之间的 sql。

  • 触发器的分类
  1. 从时间上划分:After触发器Before触发器 两种;
    After触发器 :后触发,即在表的数据更新之后触发,注意不是保存之后。
    Before触发器:增加操作用前触发,修改和删除操作用后触发
  2. 数据的修改上面划分:insert、delete、update 三种;
  3. 适用范围上划分:行级触发器和表级触发器。

2. 临时表-:new和:old.

  • 在使用触发器的时候Oracle会根据使用触发器的类型自动创建临时表-:new或者:old,里面的字段和当前所操作的表里面的字段保持一致。
  • 临时表 “:new”:做增加操作的时候Oracle会自动创建”:new”,里面用来临时存放增加过后的数据。等增加数据确认后,再把该临时表里面的数据插入到真正的表里面。等增加操作提交之后,该临时表自动消失
  • 临时表 “:old”:做删除、修改操作的时候Oracle会自动创建”:old”,里面用来临时存放删除、修改前的数据。等删除、修改操作提交后,该临时表自动消失

3. 案例数据脚本

  • 创建学生信息表
create table stuInfo(stuNo varchar2(8) not null primary key,stuName varchar2(10) not null,stuSex varchar2(2) not null,stuAge number(6) not null,stuSeat number(6) not null,strAddress varchar2(255) default('地址不详'))
  • 学生信息表增加数据
insert into stuInfo(stuNo, stuName, stuSex, stuAge,stuSeat,strAddress)select 's25301', '张秋丽', '男', 18,1, '北京海淀' from dual unionselect 's25303', '李斯文', '女', 22,2, '河阳洛阳' from dual unionselect 's25302', '李文才', '男', 85, 3,'地址不详' from dual unionselect 's25304', '欧阳俊雄', '男', 28, 4,'新疆' from dual unionselect 's25318', '梅超风', '女', 23, 5,'地址不详' from dual unionselect 's25322', '张扬a', '男', 18,1, '北京海淀' from dual
  • 创建学生成绩表
create table stuMarks(ExamNo varchar2(7) not null primary key,stuNo varchar2(6) not null references stuInfo(stuNo),writtenExam number(6) null,LabExam number(6) null)
  • 学生成绩表增加数据
insert into stuMarks(ExamNo, stuNo, writtenExam, LabExam)select 's271811', 's25303', 93, 59 from dual unionselect 's271813', 's25302', 63, 91 from dual unionselect 's271816', 's25301', 90, 83 from dual unionselect 's271817', 's25318', 63, 53 from dual

4. 触发器语法

create or replace trigger 触发器名--触发器名after insert--后触发器,而且是增加类型触发器on 表名--触发器所依赖的表for each row--行级触发器beginif :new.字段 = 0 then--触发触发器的条件dbms_output.put_line('警告:已插入记录,但数量为零');raise_application_error(-20018,'警告:已插入记录,但数量为零!'); --抛出异常,-20018是错误编码,范围是-20000-21000。end if;end;

案例1:后触发-delete操作.

  • 李思文不能被删除。
create or replace trigger stuNameafter delete on stuinfofor each rowbegin if :old.stuname='李斯文' then raise_application_error(-20018,'该学生不能删除!'); end if;end;

案例2:前触发insert&后触发delete&后触发&update.

李斯文不能删除,张三不能增加,梅超风不能修改。

create or replace trigger tnameafter delete or insert or updateon stuinfofor each rowbeginif deleting then--删除--从老表(:old)中获取删除的学生的名字并进行判断if :old.stuname='李斯文'thenraise_application_error(-20018,'该学生不能删除!');end if;elsif inserting then--增加--从新表(:new)中获取增加的学生的名字并进行判断if :new.stuname='张三' thenraise_application_error(-20019,'该学生不能要!');end if;elsif updating then--修改--从老表(:old)中获取要修改的学生的名字并进行判断if :old.stuname='梅超风' thenraise_application_error(-20020,'该学生不能修改!');end if;end if;end;

案例3:多表连删.

删除学生的同时自动删除其成绩。

create or replace trigger tnameafter deleteon stuinfofor each rowdeclare --定义变量来保存要删除的学号(也可不定义)sno varchar2(10);begin--获取删除的学生的学号sno:=:old.stuno;delete from stumarks where stuno=:old.stuno; --(或者写stuno=sno)end;

触发器+序列=标识列.


create sequence sname_01; –创建序列
–创建触发器
create or replace trigger tname
before insert
on 表名
for each row
begin
:new.sid:=sname_01.nextval;
end;

示例:实现标识列功能

创建表create table tb1(shid number,shName varchar2(10) not null)create sequence se1;--创建序列--创建触发器create or replace trigger tnamebefore inserton tb1for each rowbegin:new.sid:=se1.nextval;end;