1 1、触发器说明 2 3 触发器是一种在事件发生时隐式地自动执行的PL/SQL块,不能接受参数,不能被显式调用 4 5 2、触发器类型 6 7 根据触发器所创建的语句及所影响的对象的不同,将触发器分为以下3类 8 9 (1)DML触发器 10 11 对数据表进行DML语句操作(如insert、update、delete)时所触发的触发器,可以分为: 12 13 语句级触发器或行级触发器:行级触发器会对数据库表中的受影响的每一行触发一次触发器代码,语句级触发器则只触发一次,与语句所影响到的行数无关 14 15 before触发器或after触发器:before触发器在触发事件发生之前执行触发器代码,after触发器则在触发事件发生之后执行 16 17 语法: 18 create [or replace] trigger trigger_name 19 {before | after} trigger_event 20 on table_name 21 [for each row] 22 [when trigger_condition] 23 trigger_body 24 25 语法解释: 26 27 trigger_name:触发器名称 28 29 before | after : 指定触发器是在触发事件发生之前触发还暗示发生之后触发 30 31 trigger_event:触发事件,在DML触发器中主要为insert、update、delete等 32 33 table_name:表名,表示发生触发器作用的对象 34 35 for each row:指定创建的是行级触发器,若没有该子句则创建的是语句级触发器 36 37 when trigger_condition:添加的触发条件 38 39 trigger_body:触发体,是标准的PL/SQL语句块 40 41 42 (2)替代触发器(instead of触发器) 43 44 对视图进行操作时定义的触发器,替代触发器只能定义在视图上 45 46 语法: 47 create [or replace] trigger trigger_name --触发器名称 48 instead of trigger_event --触发事件 49 on view_name --视图名称 50 for each row --替代触发器必须指定为行级的触发器 51 [when trigger_condition] --触发条件 52 trigger_body --触发体,PL/SQL块 53 54 55 (3)系统事件触发器 56 57 对数据库实例或某个用户模式进行操作时定义的触发器,可以分为: 58 59 数据库系统触发器和用户触发器 60 61 62 3、案例 63 64 (1)DML触发器 65 66 DML触发器的案例都是基于student表和stu_log表来进行的,所以先创建student表和stu_log表 67 68 create table STUDENT 69 ( 70 id NUMBER(19), --id 71 stu_no VARCHAR2(20), --学号 72 stu_name VARCHAR2(32), --姓名 73 stu_age NUMBER, --年龄 74 stu_major VARCHAR2(32) --专业 75 ) 76 77 create table STU_LOG ( 78 log_id NUMBER, --日志id 79 log_action VARCHAR2(100), --操作名称 80 log_date DATE, --操作时间 81 log_message VARCHAR2(32) -- 82 ) 83 84 a、行级触发器(before触发器) 85 86 创建触发器:实现id的隐式自增 87 create or replace trigger modify_stu 88 before insert on student – 在插入student表之前 89 for each row – 每一行都会触发这个触发器 90 declare 91 next_id number; 92 begin 93 select seq_test.nextval into next_id from dual; 94 :new.id :=next_id; 95 end; 96 97 插入一条数据,但是不插入id 98 99 insert into student(stu_no,stu_name,stu_age,stu_major) values('NO1','张三',20,'中文系'); 100 101 查询结果如下,自动生成id了 102 103 104 b、 行级触发器(after触发器) 105 106 创建触发器:将对student表的操作都记录到stu_log表中(update of 用于指定一个或多个字段,指定字段被更新时才会触发触发器) 107 create or replace trigger modify_stu 108 after insert or delete or update of stu_name – 任何人对stuname这个属性进行DML操作 109 on student 110 for each row 111 begin 112 if inserting then 113 insert into stu_log values(1,'insert',sysdate,:new.stu_name); 114 elsif deleting then 115 insert into stu_log values(2,'delete',sysdate,:old.stu_name); 116 elsif updating then 117 insert into stu_log values(3,'update_old',sysdate,:old.stu_name); 118 insert into stu_log values(4,'update_new',sysdate,:new.stu_name); 119 end if; 120 end; 121 122 insert into student values(1,'NO2','李四',21,'数学系'); --插入一条数据 123 delete student where stu_name='张三'; --删除一条数据 124 update student set stu_age=19 where stu_name='李四'; --修改李四的年龄 125 update student set stu_name='王二' where stu_name='李四'; --修改李四的名称 126 127 查询stu_log表的结果如下,第3条update语句没有触发该触发器,因为触发器指定只有修改stu_name字段才会触发触发器 128 129 130 c、语句级触发器(before触发器):用来控制对表的修改 131 132 create or replace trigger modify_stu 133 before insert or update or delete on student 134 begin 135 if deleting then 136 raise_application_error(-20001,'该表不允许删除数据'); 137 elsif updating then 138 raise_application_error(-20002,'该表不允许修改数据'); 139 elsif inserting then 140 raise_application_error(-20003,'该表不允许插入数据'); 141 end if; 142 end; 143 144 插入数据时报错如下,删除和修改数据同样也报错 145 146 147