Oracle 触发器语法及实例(二)
2、触发器的类型有:
触发器类型:
1、 语句触发器
2、 行触发器
3、INSTEAD OF触发
4、 系统条件触发器
5、 用户事件触发器
2.1、语句级触发器.(语句级触发器对每个DML语句执行一次)
是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次。比如,无论update多少行,也只会调用一次update语句触发器。
实例:
createorreplacetriggertri_test afterinsertorupdateordeleteontest begin ifupdatingthen dbms_output.put_line(‘修改‘); elsifdeletingthen dbms_output.put_line(‘删除‘); elsifinsertingthen dbms_output.put_line(‘插入‘); endif; end;
2.2、行级触发器.(行级触发器对DML语句影响的每个行执行一次)
实例一:
触发器 行级触发器
createtabletest(sidnumber,snamevarchar2(20));--创建一个表 createsequenceseq_test;--创建序列 createorreplacetriggertri_test--创建触发器 beforeinsertorupdateofsidontest foreachrow--触发每一行 begin ifinsertingthen selectseq_test.nextvalinto:new.sidfromdual; else raise_application_error(-20020,‘不允许更新ID值!‘);--中断程序 endif; end;
测试,插入几条记录
insertintotestvalues(0,‘ff‘); insertintotestvalues(0,‘ff‘); insertintotestvalues(0,‘tt‘);
实例二:
创建一个触发器,无论用户插入新记录,还是修改emp表的job列,都将用户指定的job列的值转换成大写.
createorreplacetriggertrig_job beforeinsertorupdateofjob onemp foreachrow begin ifinsertingthen :new.job:=upper(:new.job); else :new.job:=upper(:new.job); endif; end;
2.3、instead of触发器.
(此触发器是在视图上而不是在表上定义的触发器,它是用来替换所使用实际语句的触发器.)
语法如下:
createorreplacetriggertrig_test insteadofinsertorupdateon表名 referencingnewasn foreachrow declare .......... begin ........ end;
2.4、模式触发器.
可以在模式级的操作上建立触发器.
实例如下:
createorreplacetriggerlog_drop_obj afterdroponschema begin insertinto..... end;
2.5、数据库级触发器.
可以创建在数据库事件上的触发器,包括关闭,启动,服务器错误,登录等.这些事件都是实例范围的,不与特定的表或视图关联.
实例:
createorreplacetriggertrig_name afterstartupondatabase begin ........... end;
2.6、例子:
需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。
Createtablefoo(anumber); Createtriggerbiud_foo Beforeinsertorupdateordelete Onfoo Begin Ifusernotin(‘DONNY’)then Raise_application_error(-20001,‘Youdon’thaveaccesstomodifythistable.’); Endif; End; /
即使SYS,SYSTEM用户也不能修改foo表
2.7、[试验]
对修改表的时间、人物进行日志记录。
1、 建立试验表
createtableemployees_copyasselect*fromhr.employees
2、 建立日志表
createtableemployees_log( whovarchar2(30), whendate);
3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log表。
Createorreplacetriggerbiud_employee_copy Beforeinsertorupdateordelete Onemployees_copy Begin Insertintoemployees_log(Who,when) Values(user,sysdate); End; /
4、 测试
updateemployees_copysetsalary=salary*1.1; select*fromemployess_log;
5、 确定是哪个语句起作用?
即是INSERT/UPDATE/DELETE中的哪一个触发了触发器?
可以在触发器中使用INSERTING / UPDATING / DELETING条件谓词,作判断:
begin ifinsertingthen ----- elsifupdatingthen ----- elsifdeletingthen ------ endif; end; ifupdating(‘COL1’)orupdating(‘COL2’)then ------ endif;
2.8、[试验]
1、 修改日志表
altertableemployees_log add(actionvarchar2(20));
2、 修改触发器,以便记录语句类型。
then l_action:=’Delete’; else raise_application_error(-20001,’Youshouldneverevergetthiserror.’); Insertintoemployees_log(Who,action,when) Values(user,l_action,sysdate); End;Createorreplacetriggerbiud_employee_copy Beforeinsertorupdateordelete Onemployees_copy Declare L_actionemployees_log.action%type; Begin ifinsertingthen l_action:=’Insert’; elsifupdatingthen l_action:=’Update’; elsifdeleting /
3、测试insertintoemployees_copy(employee_id,last_name,email,hire_date,job_id) values(12345,’Chen’,’Donny@hotmail’,sysdate,12); select*fromemployees_log
| 广告合作:400-664-0084 全国热线:400-664-0084 Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号 珠峰网 版权所有 All Rights Reserved
|