触发器
当我们在数据库执行 DML(insert update delete) 和DDL(create alter drop) 自动调用一个存储过程(只能写增,删,改,赋值)
不能被显示调用
类型
ORACLE数据库有四种触发器,分别是DML、Instead-of、DDL、DB触发器,一般的应用系统中都是用到DML、Instead-of触发器,DDL、DB两种触发器是DBA管理数据库用得比较多
四种触发器分别有不同的作用
一、DML触发器:当发出UPDATE、INSERT、DELETE命令就可以触发已定义好的DML触发器,是最简单和常用的一种触发器
语法:
create or replace trigger trigger_name after|before insert|update|delete on table_name for each row
[when condition]
二、Instead-of触发器:当向一个由多个表联接成的视图作DML操作时,一般情况下是不允许的,这时候就可以用Instead-of触发器来解决这种问题(在触发器写代码分别对各表作相应DML操作),
create or replace trigger trigger_name
使用注意事项
1. 触发器不接受参数。
2. 一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。并各触发器之间不能有矛盾。
3. 在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大。
4. 触发器最大为32KB。若确实需要,可以先建立过程,然后在触发器中用CALL语句进行调用。
5. 在触发器的执行部分只能用DML语句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL语句(CREATE、ALTER、DROP)。
6. 触发器中不能包含事务控制语句(COMMIT,ROLLBACK,SAVEPOINT)。因为触发器是触发语句的一部分,触发语句被提交、回退时,触发器也被提交、回退了。
7.在触发器主体中调用的任何过程、函数,都不能使用事务控制语句。
8. 在触发器主体中不能申明任何Long和blob变量。新值new和旧值old也不能是表中的任何long和blob列。
9. 不同类型的触发器(如DML触发器、INSTEAD OF触发器、系统触发器)的语法格式和作用有较大区别。
--语句级别触发器
--只要这个语句被执行,触发器只执行一次
create or replace trigger trig1
before update on bak
begin
dbms_output.put_line('修改!');
end;
--分别监听多个
create or replace trigger trig1
before update or delete or insert on bak
begin
if updating then
dbms_output.put_line('修改!');
elsif inserting then
dbms_output.put_line('新增!');
elsif deleting then
dbms_output.put_line('删除!');
end if;
end;
--例子
create or replace trigger trig1
after update or insert or delete on bak
declare
v bak.sal%type;
begin
select sum(sal) into v from bak;
dbms_output.put_line('工资总额:' ||v);
end;
update bak set sal=sal+10 where deptno=100;
delete bak;
--行级触发器 for each row
--有多少行受影响,执行多少次
create or replace trigger trig2
after update on bak
for each row
begin
dbms_output.put_line('修改!');
end;
update bak set sal=sal+10;
--行级触发器 for each row
--:old 临时保存 delete,update 前的受影响的这一行
:new 临时保存了 insert update 后受影响的这一行
create or replace trigger trig2
after update on bak
for each row
begin
dbms_output.put_line('修改了前:'||:old.sal );
dbms_output.put_line('修改了后:'||:new.sal );
end;
update bak set sal=sal+10;
--模式触发器
create or replace trigger trig3
after drop on schema
begin
dbms_output.put_line(ora_dict_obj_name);
dbms_output.put_line(ora_dict_obj_type);
dbms_output.put_line(sysdate);
end;
drop table bak;
--中断DML操作
create or replace trigger trig4
before delete on emp
begin
raise_application_error(1111,'不能删除数据');--自定义一个异常错误,当删除emp表的时候会弹出一个警告框
end;
delete emp;