Oracle触发器简单使用记录
在ORACLE系统里,触发器类似函数和过程。 语法: 2、简例 例1: create or replace trigger insert_emp after insert on emp_bak1 for each row declare --Declare后面跟的是本地变量定义部分,如果没有本地变量定义,此部分可以去掉 test_val emp_bak1.ename%type;--根据表的字段定义变量类型 begin dbms_output.put_line(‘员工编号:‘||:new.empno); dbms_output.put_line(‘员工姓名:‘||:new.ename); dbms_output.put_line(‘职位:‘||:new.job); dbms_output.put_line(‘工资:‘||:new.sal); dbms_output.put_line(‘所在部门:‘||:new.deptno); dbms_output.put_line(‘---触发器已被执行---‘); --select ename into test_val from emp_bak1 where empno = 7839;--ORA-04091 select :new.empno into test_val from dual; dbms_output.put_line(‘---测试--->‘||test_val); end; insert into emp_bak1 (empno,ename,job,sal,deptno) values (‘666‘,‘SM‘,‘IT‘,‘800‘,‘20‘); oracle默认的 用old代表老数据 new代表新数据(这两个变量只有在使用了关键字 "FOR EACH ROW"时才存在;referencing new as new_val old as old_val:这个可以更改新旧值的名字来引用新值,旧值) create or replace trigger delete_emp before delete on emp_bak1 --删除操作前触发 for each row begin insert into emp_bak2 (empno,deptno) values (:old.empno,:old.ename,:old.job,:old.sal,:old.deptno); dbms_output.put_line(‘-----有数据删除,员工号为‘||:old.empno||‘详细信息见emp_bak2表------‘); end delete_emp; insert into emp_bak1 (empno,deptno) values (‘777‘,‘K‘,‘TE‘,‘1000‘,‘30‘); delete from emp_bak1 where empno = 777; 例2:指定条件列触发 create or replace trigger tri_01 after insert or update of sal on emp_bak1 for each row begin if inserting then dbms_output.put_line(‘新人入驻有收入sal‘); elsif updating then dbms_output.put_line(‘sal有变动‘); end if; end tri_01; update emp_bak1 set sal = 888 where empno = 7934;--触发 update emp_bak1 set comm = 666 where empno = 7934;--未触发 注:第二行中的of sal on emp_bak1 是在表emp_bak1的sal字段发生变更时才触发操作, 例3:when条件限制 create or replace trigger tri_02 before update of sal,comm or delete on emp_bak1 for each row when (old.deptno = 30) --注:old前不带‘:‘且结尾不带‘;‘ begin case when updating(‘sal‘) then dbms_output.put_line(‘原来薪资:‘||:old.sal||‘;变更后薪资:‘||:new.sal||‘;‘); if :new.sal < :old.sal then dbms_output.put_line(‘降薪不被允许‘); raise_application_error(-20001,‘部门30的人员的工资不能降‘); end if; when updating(‘comm‘) then dbms_output.put_line(‘原来奖金:‘||:old.comm||‘;变更后奖金:‘||:new.comm||‘;‘); if :new.comm < :old.comm then dbms_output.put_line(‘降奖金不被允许‘); raise_application_error(-20002,‘部门30的人员的奖金不能降‘); end if; when deleting then raise_application_error(-20003,‘部门30的人员不能删‘); end case; end; select * from emp_bak1 where deptno = 30; raise_application_error相当于拒绝了插入或者修改事务 例4:instead of触发器 --语法类似: create [or replace] trigger trigger_name instead of {insert | delete | update [of column [,column …]]} on view_name --只能定义在视图上 [referencing {old [as] old_val | new [as] new_val| parent as parent}]--可以给old/new对象赋予新的名称(可以不要) [for each row ] --因为instead of触发器只能在行级上触发,所以没有必要指定 [when condition] pl/sql_block | call procedure_name; 视图创建 create view view_emp as select deptno,count(*) count_no,sum(sal) sal from emp group by deptno;
create or replace trigger view_tri_03 instead of delete on view_emp for each row begin delete from emp where deptno= :old.deptno; dbms_output.put_line(‘从emp基表中删除部门编号为:‘||:old.deptno||‘的基础人员数据。‘); end view_tri_03; 可看出此触发器只是触发了一个删除部门号的事件,实际更改的还是基表。 例5:语句级触发器 create or replace trigger tri_04 after insert or update of sal on emp_bak1 declare v_sumsal number; begin select sum(sal) into v_sumsal from emp_bak1; if v_sumsal > 50000 then raise_application_error(-20001,‘总工资超过50000‘); end if; end; --如果用行级触发器(for each row)会报ORA-04091错误 insert into emp_bak1 (empno,deptno) values (‘777‘,‘K‘,‘TE‘,‘90000‘,‘30‘); ? (注:此为学习记录笔记,仅供参考若有问题请指正,后续补充......) ? 参考资料:https://www.cnblogs.com/wishyouhappy/p/3665851.html 参考资料:https://blog.csdn.net/weiwenhp/article/details/9179891 参考资料:https://www.cnblogs.com/hyq0002013/p/6085981.html 参考资料:https://blog.csdn.net/IndexMan/article/details/8023740 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |