加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ORACLE触发器

发布时间:2020-12-12 13:14:26 所属栏目:百科 来源:网络整理
导读:ORACLE触发器(trigger)的使用 1、触发器说明 触发器是一种在事件发生时隐式地自动执行的PL/SQL块,不能接受参数,不能被显式调用 2、触发器类型 根据触发器所创建的语句及所影响的对象的不同,将触发器分为以下3类 (1)DML触发器 对数据表进行DML语句操作

ORACLE触发器(trigger)的使用

1、触发器说明

触发器是一种在事件发生时隐式地自动执行的PL/SQL块,不能接受参数,不能被显式调用

2、触发器类型

根据触发器所创建的语句及所影响的对象的不同,将触发器分为以下3类

(1)DML触发器

对数据表进行DML语句操作(如insert、update、delete)时所触发的触发器,可以分为:

语句级触发器或行级触发器:行级触发器会对数据库表中的受影响的每一行触发一次触发器代码,语句级触发器则只触发一次,与语句所影响到的行数无关

before触发器或after触发器:before触发器在触发事件发生之前执行触发器代码,after触发器则在触发事件发生之后执行

  1. 语法:
  2. create [or replace] trigger trigger_name
  3. { before | after} trigger_event
  4. on table_name
  5. [ for each row]
  6. [ when trigger_condition]
  7. trigger_body

语法解释:

trigger_name:触发器名称

before | after : 指定触发器是在触发事件发生之前触发还暗示发生之后触发

trigger_event:触发事件,在DML触发器中主要为insert、update、delete等

table_name:表名,表示发生触发器作用的对象

for each row:指定创建的是行级触发器,若没有该子句则创建的是语句级触发器

when trigger_condition:添加的触发条件

trigger_body:触发体,是标准的PL/SQL语句块

?

(2)替代触发器(instead of触发器)

对视图进行操作时定义的触发器,替代触发器只能定义在视图上

  1. 语法:
  2. create [or replace] trigger trigger_name --触发器名称
  3. instead of trigger_event --触发事件
  4. on view_name --视图名称
  5. for each row --替代触发器必须指定为行级的触发器
  6. [ when trigger_condition] --触发条件
  7. trigger_body --触发体,PL/SQL块

?

(3)系统事件触发器

对数据库实例或某个用户模式进行操作时定义的触发器,可以分为:

数据库系统触发器和用户触发器

?

3、案例

(1)DML触发器

DML触发器的案例都是基于student表和stu_log表来进行的,所以先创建student表和stu_log表

  1. create table STUDENT ---创建student表
  2. (
  3. id NUMBER(19),--id
  4. stu_no VARCHAR2( 20),--学号
  5. stu_name VARCHAR2( 32),--姓名
  6. stu_age NUMBER,--年龄
  7. stu_major VARCHAR2( 32) --专业
  8. )
  1. create table STU_LOG ---创建stu_log表,用于记录对student表的操作日志
  2. (
  3. log_id NUMBER,--日志id
  4. log_action VARCHAR2( 100),--操作名称
  5. log_date DATE,--操作时间
  6. log_message VARCHAR2( 32) --
  7. )

?a、行级触发器(before触发器)

  1. 创建触发器:实现id的隐式自增
  2. create or replace trigger modify_stu
  3. before insert on student
  4. for each row
  5. declare
  6. next_id number;
  7. begin
  8. select seq_test.nextval into next_id from dual;
  9. :new.id :=next_id;
  10. end;

插入一条数据,但是不插入id

insert into student(stu_no,stu_name,stu_age,stu_major) values(‘NO1‘,‘张三‘,20,‘中文系‘); 

查询结果如下,自动生成id了

?

b、 行级触发器(after触发器)

  1. 创建触发器:将对student表的操作都记录到stu_log表中( update of 用于指定一个或多个字段,指定字段被更新时才会触发触发器)
  2. create or replace trigger modify_stu
  3. after insert or delete or update of stu_name
  4. on student
  5. for each row
  6. begin
  7. if inserting then
  8. insert into stu_log values(1,‘insert‘,sysdate,:new.stu_name);
  9. elsif deleting then
  10. insert into stu_log values(2,‘delete‘,:old.stu_name);
  11. elsif updating then
  12. insert into stu_log values(3,‘update_old‘,:old.stu_name);
  13. insert into stu_log values(4,‘update_new‘,:new.stu_name);
  14. end if;
  15. end;
  1. insert into student values(1,‘NO2‘,‘李四‘,21,‘数学系‘); --插入一条数据
  2. delete student where stu_name=‘张三‘; --删除一条数据
  3. update student set stu_age=19 where stu_name=‘李四‘; --修改李四的年龄
  4. update student set stu_name=‘王二‘ where stu_name=‘李四‘; --修改李四的名称

查询stu_log表的结果如下,第3条update语句没有触发该触发器,因为触发器指定只有修改stu_name字段才会触发触发器

?c、语句级触发器(before触发器):用来控制对表的修改

  1. create or replace trigger modify_stu
  2. before insert or update or delete on student
  3. begin
  4. if deleting then
  5. raise_application_error( -20001,‘该表不允许删除数据‘);
  6. elsif updating then
  7. raise_application_error(-20002,‘该表不允许修改数据‘);
  8. elsif inserting then
  9. raise_application_error(-20003,‘该表不允许插入数据‘);
  10. end if;
  11. end;

插入数据时报错如下,删除和修改数据同样也报错

?d、语句级触发器(after触发器):略

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读