Oracle触发器
触发器是在事件发生时隐式地自动运行的PL/SQL程序块,不能接收参数,不能被调用。
触发器不能被显式调用
触发器的功能:
自动生成数据
自定义复杂的安全权限
提供审计和日志记录
启用复杂的业务逻辑
触发器分为数据库触发器和DML触发器
数据库触发器:对数据库对象进行创建,删除和修改的时候触发
DML触发器:对数据进行操作时进行触发,主要是插入,修改,删除操作
触发器分类
根据触发的次数分为:行级(每行都会触发),语句级(只触发一次)
根据触发的时间分为:前置(执行语句前触发),后置(执行语句后触发),替代(不执行语句)
触发器的基本要素
触发器有以下部分组成:
触发源:是什么对象触发的?通常是一个表或试图
触发事件:如插入,更新,删除
触发时机:前置或后置,还是直接替代触发事件
触发器限制:用户对触发器的控制,当禁用时触发器无效
触发动作:触发器被触发时执行的动作
创建触发器的语法
create [or replace] trigger 触发器名
before | after | instead of --触发时机,三选一
insert [or update or insert]
on 表|视图
[for each row]--行级触发器,不指定语句级触发器,语句不能使用new和old
[when (触发条件):]
[declare
变量名 数据类型;
]
begin
触发语句;
end;
各类触发器的使用案例
create or replace trigger text_info
before --前置
delete or update or insert --执行删除,更新,插入时执行
on text --在text表中建立触发器
[for each row
when (new.stuid!=0 or old.stuid!=0)]
declare
name varchar2(20):='管理员';
begin
if updating then
dbms_output.put_line('修改了该表');
elsif deleting then
dbms_output.put_line('删除了该表数据');
elsif inserting then
dbms_output.put_line('在该表插入了数据');
else
dbms_output.put_line('错误');
end if;
end;
Old new 系统表
行级触发器中的系统表new old:
old: 存放删除,修改前的旧数据行
new:存放添加,修改后的新数据行
使用注意:
1:when条件中直接加 new.列名
2:begin中使用前加 :new.列名 :old.列名
例:
--分数小于0时显示添加的最新数据
CREATE OR REPLACE TRIGGER 触发器名
BEFORE
INSERT ON 表名
FOR EACH ROW --行级触发器
when (new.score <0)
begin
dbms_output.put_line(:new.scoreid||'-'||:new.stuid||'-'||:new.score);
替代触发器
替代触发器帮我们解决了:当我们去想要修改视图时,如果视图是多表来联合查询,我们不能直接修改视图的过程中,修改基表。
语法:
create or replace trigger 触发器名
instead of --替代触发器,只执行触发器,不执行语句本身
insert or update
on 视图名
for each row
begin
insert into 表1 VALUES(:NEW.表1列名,:NEW.表1列名,:NEW.表1列名,:NEW.表1列名,);
insert into 表2 VALUES(:NEW.表2列名,:NEW.表2列名,:NEW.表2列名,:NEW.表2列名,);
insert into 表3 VALUES(:NEW.表3列名,:NEW.表3列名,:NEW.表3列名,:NEW.表3列名,);
触发器的管理
将单个触发器禁用或启用
ALTER TRIGGER 触发器名称 DISABLE|ENABLE
将一个表上的所有触发器全部禁用或启用
ALTER TABLE 表名 DISABLE | ENABLE ALL TRIGGER
SELECT TRIGGER_NAME FROM USER_TRIGGERS WHERE TABLE_NAME='EMP'
SELECT TRIGGER_TYPE ,TRIGGERING_EVENT,WHEN_CLAUSE FROM USER_TRIGGERS WHERE TRIGGER_NAME ='BIU_EMP_DEPTNO';