版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 Hands-On实训教程系列实训教程系列专题八专题八 触发器触发器 Hands-On实训教程系列实训教程系列回顾回顾l过程和函数都是命名的过程和函数都是命名的PL/SQL程序块,合称子程序程序块,合称子程序l过程有三种参数模式:过程有三种参数模式:IN、OUT和和IN OUTl过程用户执行特定的任务,函数用于执行任务并返过程用户执行特定的任务,函数用于执行任务并返回值回值l过程与函数的相同点和不同点过程与函数的相同点和不同点l程序包是对过程、函数、变量、常量、游标、异常程序包是对过程、函数、变量、常量、游标、异常及及PL/SQL数据类型等的封装数据类型等的封装 l程序包由两部分组成,即包规范
2、和包主体程序包由两部分组成,即包规范和包主体l使用程序包的优点使用程序包的优点 Hands-On实训教程系列实训教程系列教学目标l了解触发器的概念和作用了解触发器的概念和作用l理解触发器的设计原则理解触发器的设计原则l掌握触发器的组成部分掌握触发器的组成部分l熟练使用熟练使用DML触发器触发器l了解了解INSTEAD OF触发器和系统触发器触发器和系统触发器l掌握触发器的查看、禁用、激活和删除掌握触发器的查看、禁用、激活和删除 Hands-On实训教程系列实训教程系列工作任务 l 使用使用BEFORE行级触发器行级触发器l 使用使用AFTER行级触发器行级触发器l 使用使用BEFORE语句级触
3、发器语句级触发器l 使用使用AFTER语句级触发器语句级触发器l 使用使用INSTEAD OF触发器触发器l 使用使用DDL触发器触发器l 使用数据库启动和关闭触发器使用数据库启动和关闭触发器l 使用用户登录和退出触发器使用用户登录和退出触发器l 管理触发器管理触发器 Hands-On实训教程系列实训教程系列相关实践知识相关实践知识l触发器触发器是当某一事件发生时自动执行的特殊的是当某一事件发生时自动执行的特殊的过程,利用它我们可以实现复杂的约束和业务过程,利用它我们可以实现复杂的约束和业务逻辑,实现更高的数据安全性。逻辑,实现更高的数据安全性。 Hands-On实训教程系列实训教程系列BEF
4、ORE行级触发器行级触发器6-1 l公司规定,如果给员工加薪,每次的加公司规定,如果给员工加薪,每次的加薪比例不能超过本人原工资的薪比例不能超过本人原工资的10%,为,为实现这一功能,可以在表实现这一功能,可以在表emp上建立一上建立一个个BEFORE行级触发器行级触发器(DML触发器中触发器中的一种)。的一种)。l1. 从开始菜单中打开从开始菜单中打开SQL*Plus工具,以工具,以SCOTT用户的身份登录到数据库。用户的身份登录到数据库。l2. 在在SQL提示符下输入如下的代码来创提示符下输入如下的代码来创建触发器。建触发器。 Hands-On实训教程系列实训教程系列BEFORE行级触发器
5、行级触发器6-2lCREATE OR REPLACE TRIGGER tr_emp_bef_rowlBEFORE UPDATE OF sallON emplFOR EACH ROWlDECLAREll_scale NUMBER;lBEGINll_scale:=(:NEW.sal-:OLD.sal)/:OLD.sal;lIF l_scale0.1 THENlDBMS_OUTPUT.PUT_LINE(对不起对不起,员工的加薪比例不能超过员工的加薪比例不能超过10%!);l:NEW.sal:=:OLD.sal*1.1;lEND IF;lEND TRIGGER;l/ Hands-On实训教程系列实训教
6、程系列BEFORE行级触发器行级触发器6-3l3. 按回车键后,系统提示按回车键后,系统提示“触发器已创建触发器已创建”,说明触发器创建成功。说明触发器创建成功。l4. 假如现在要给编号是假如现在要给编号是7369的员工加薪。先的员工加薪。先用如下的查询语句查看一下他的原工资。用如下的查询语句查看一下他的原工资。 SELECT empno,sal FROM emp WHERE empno=7369;l可以查出编号是可以查出编号是7369的员工的原工资是的员工的原工资是800。 Hands-On实训教程系列实训教程系列BEFORE行级触发器行级触发器6-4l5. 计划给该员工加薪到计划给该员工加
7、薪到1000,用如下的,用如下的UPDATE语句修改。语句修改。 UPDATE emp SET sal=1000 WHERE empno=7369;l6. 按回车后,系统提示按回车后,系统提示“对不起对不起,员工的加薪员工的加薪比例不能超过比例不能超过10%!“和和”已更新一行已更新一行”,再同,再同第第4步相同的查询语句,查看该员工的工资,步相同的查询语句,查看该员工的工资,结果如图所示。结果如图所示。l从图中可以看出,该员工的工资被修改为从图中可以看出,该员工的工资被修改为880,而不是而不是1000,触发器被执行。,触发器被执行。 Hands-On实训教程系列实训教程系列BEFORE行级
8、触发器行级触发器6-5l7. 假定现在公司的规定变为:只有原工资高于假定现在公司的规定变为:只有原工资高于1500的员工加薪才不能超过的员工加薪才不能超过10%,低于,低于 1000的不再受此的不再受此限制。可在第限制。可在第2步的创建触发器的代码中,在步的创建触发器的代码中,在FOR EACH ROW子句的后面加入如下触发条件。子句的后面加入如下触发条件。WHEN (OLD.sal1500)l8. 创建触发器成功后,继续用如下的创建触发器成功后,继续用如下的UPDATE语句语句想把编号是想把编号是7369的员工的工资改为的员工的工资改为1000。UPDATE emp SET sal=1000
9、 WHERE empno=7369; Hands-On实训教程系列实训教程系列BEFORE行级触发器行级触发器6-6l9. 语句执行后系统提示语句执行后系统提示“已更新一行已更新一行”,再用语句,再用语句查询可以查出该员工的工资被更新为查询可以查出该员工的工资被更新为1000。而不是。而不是8801.1=968,可见因为触发条件的限制,触发器,可见因为触发条件的限制,触发器内的触发操作语句并没有被执行。内的触发操作语句并没有被执行。l10. 如果把创建触发器的代码中的如果把创建触发器的代码中的“BEFORE”改为改为“AFTER”,按回车后将会出现如图所示的结果。,按回车后将会出现如图所示的结
10、果。l由此可见,由此可见,只能在只能在BEFORE行级触发器中重新设置行级触发器中重新设置NEW值值 ,而不能在,而不能在AFTER触发器中更改触发器中更改NEW值。值。 Hands-On实训教程系列实训教程系列AFTER行级触发器行级触发器3-1 l现要审计员工的工资变动情况,用一个表来记现要审计员工的工资变动情况,用一个表来记录相关信息,利用录相关信息,利用AFTER行级触发器向表中行级触发器向表中插入数据。插入数据。l1. 以以SCOTT用户身份登录到数据库后,建立用户身份登录到数据库后,建立记录工资变动情况的表记录工资变动情况的表t_em_sal_change,在在SQL提示符下输入如
11、下的建表语句。提示符下输入如下的建表语句。lCREATE TABLE t_emp_sal_changel(ltime DATE,lempno NUMBER(4),loldsal NUMBER(7,2),lnewsal NUMBER(7,2)l); Hands-On实训教程系列实训教程系列AFTER行级触发器行级触发器3-2l2. 在在SQL提示符下,输入以下的代码来创建提示符下,输入以下的代码来创建AFTER行级触发器。行级触发器。lCREATE OR REPLACE TRIGGER tr_emp_aft_rowlAFTER UPDATE OF sallON emplFOR EACH ROWl
12、BEGINlINSERT INTO t_emp_sal_change lVALUES(systimestamp,:OLD.empno,:OLD.sal,:NEW.sal);lEND TRIGGER;l/ Hands-On实训教程系列实训教程系列AFTER行级触发器行级触发器3-3l3. 修改部门编号是修改部门编号是10的所有员工的工资,给的所有员工的工资,给每人加薪每人加薪100。UPDATE emp SET sal=sal+100 WHERE deptno=10;l4. 语句执行后系统提示语句执行后系统提示“已更新已更新3行行”,再用,再用SELECT语句查询表语句查询表t_em_sal_c
13、h-ange内的内的信息,如图所示。信息,如图所示。l可见,利用可见,利用AFTER行级触发器,员工工资的行级触发器,员工工资的变动情况被自动记录到表变动情况被自动记录到表t_emp_sal_change中,实现了对工资变动情况的审计。中,实现了对工资变动情况的审计。 Hands-On实训教程系列实训教程系列BEFORE语句级触发器语句级触发器5-1lemp表中包括员工工资等敏感数据,为了防止表中包括员工工资等敏感数据,为了防止有人随意修改,公司规定只有有人随意修改,公司规定只有SCOTT用户才用户才有权修改此表,现通过在有权修改此表,现通过在emp表上建立表上建立BEFORE语句级触发器来实
14、现此功能。语句级触发器来实现此功能。l1. 以以SCOTT用户身份登录到数据库后,在用户身份登录到数据库后,在SQL提示符下,输入以下的代码来创建提示符下,输入以下的代码来创建BE-FORE语句级触发器。语句级触发器。 Hands-On实训教程系列实训教程系列BEFORE语句级触发器语句级触发器5-2lCREATE TRIGGER tr_emp_beflBEFORE INSERT OR UPDATE OR DELETElON emplBEGINlIF user NOT IN (SCOTT) THENlRAISE_APPLICATION_ERROR(-20001,您无权修改您无权修改emp表表)
15、;lEND IF;lEND TRIGGER;l/ Hands-On实训教程系列实训教程系列BEFORE语句级触发器语句级触发器5-3l2. 系统提示系统提示“触发器已创建触发器已创建“后,为了测试后,为了测试触发器是否能真正实现功能,在触发器是否能真正实现功能,在SQL提示符下提示符下输入如下的代码,以输入如下的代码,以SYSDBA身份登录到数身份登录到数据库。据库。CONNECT / AS SYSDBA;l3. 系统管理员想向表系统管理员想向表emp中插入一条记录,中插入一条记录,在在SQL提示符下输入如下的代码。提示符下输入如下的代码。INSERT INTO emp(empno,ename
16、) VALUES(8888,aaa); Hands-On实训教程系列实训教程系列BEFORE语句级触发器语句级触发器5-4l4. 按回车后系统出现如图所示的错误提示。按回车后系统出现如图所示的错误提示。 Hands-On实训教程系列实训教程系列BEFORE语句级触发器语句级触发器5-5l5. 在在SQL提示符下,输入如下的代码,以提示符下,输入如下的代码,以SCOTT用户的身份登录到数据库。用户的身份登录到数据库。CONNECT SCOTT/TIGER;l6. 输入与上面第输入与上面第3步相同的代码,系统提示步相同的代码,系统提示“已创建一行已创建一行”,说明操作成功。,说明操作成功。l从以上
17、的操作可以看出,加上此从以上的操作可以看出,加上此BEFORE语语句级触发器后,不允许除句级触发器后,不允许除SCOTT用户之外的用户之外的其他任何用户修改表其他任何用户修改表emp,即使管理员也不行。,即使管理员也不行。 Hands-On实训教程系列实训教程系列AFTER语句级触发器语句级触发器4-1 l为了审计数据库用户对表为了审计数据库用户对表emp所做的所做的DML操操作,可以用作,可以用AFTER语句级触发器来实现此功语句级触发器来实现此功能。能。l1. 以以SCOTT用户的身份登录到数据库,在用户的身份登录到数据库,在SQL提示符下,输入如下的代码,创建记录提示符下,输入如下的代码
18、,创建记录DML操作的表操作的表t_emp_dml。lCREATE TABLE t_emp_dmll(lwho VARCHAR2(10),lwhen DATE,loperater VARCHAR2(10)l); Hands-On实训教程系列实训教程系列AFTER语句级触发器语句级触发器4-2l2. 输入如下的代码创建输入如下的代码创建AFTER语句级触发器。语句级触发器。lCREATE OR REPLACE TRIGGER tr_emp_aftlAFTER INSERT OR UPDATE OR DELETElON emplBEGINlCASElWHEN INSERTING THENlINSE
19、RT INTO t_emp_dml VALUES(user,sysdate,INSERT);lWHEN UPDATING THENlINSERT INTO t_emp_dml VALUES(user,sysdate,UPDATE);lWHEN DELETING THENlINSERT INTO t_emp_dml VALUES(user,sysdate,DELETE);lEND CASE;lEND TRIGGER;l/ Hands-On实训教程系列实训教程系列AFTER语句级触发器语句级触发器4-3l3. 按回车系统提示按回车系统提示“触发器已创建触发器已创建”后,为后,为验证其功能,在验证其
20、功能,在SQL提示符下按如下的代码所提示符下按如下的代码所示输入一些测试数据。示输入一些测试数据。l4. 用如下的用如下的SELECT语句查询表语句查询表t_emp_dml的内容。的内容。SELECT * FROM t_emp_dml;lINSERT INTO emp(empno,ename) VALUES(1000,TEST1);lINSERT INTO emp(empno,ename) VALUES(1000,TEST2);lUPDATE emp SET ename=TEST3 WHERE empno=1000;lDELETE FROM emp WHERE empno=1000 OR em
21、pno=1001; Hands-On实训教程系列实训教程系列AFTER语句级触发器语句级触发器4-4l5. 查询结果如图所示。查询结果如图所示。l可以看出,表可以看出,表t_emp_dml记录了对表记录了对表emp的的DML操操作。请注意上面第作。请注意上面第3步中的步中的DELETE语句尽管一次删语句尽管一次删除了两条记录,但因为是语句级触发器而非行级触除了两条记录,但因为是语句级触发器而非行级触发器,所以只在表发器,所以只在表t_emp_dml添加了一条信息。添加了一条信息。 Hands-On实训教程系列实训教程系列小结:小结: DML触发器的触发顺序触发器的触发顺序l如果在一个表上同时定
22、义了多种如果在一个表上同时定义了多种DML触触发器,则当执行发器,则当执行DML操作时,各种操作时,各种DML触发器的触发顺序如下:触发器的触发顺序如下:l1. BEFORE语句级触发器语句级触发器l2. BEFORE行级触发器行级触发器l3. AFTER行级触发器行级触发器l4. AFTER语句级触发器语句级触发器 Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器6-1 l本例演示了本例演示了INSTEAD OF触发器触发器 的使用方法的使用方法l1. 基于表基于表emp和和dept创建视图创建视图v_dept_emp,如下面的代码所示。如下面的代码所示。l2. 视图
23、创建完成后,可以正常地执行查询语视图创建完成后,可以正常地执行查询语句。如可以用下面的代码来查询视图。句。如可以用下面的代码来查询视图。SELECT * FROM v_dept_emp;lCREATE OR REPLACE VIEW v_dept_empASSELECT d.deptno,d.dname,e.empno,e.enameFROM dept d,emp eWHERE d.deptno=e.deptno; Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器6-2l查询结果如图所示。查询结果如图所示。l3. 但是,如果想用如下的但是,如果想用如下的INSERT语句
24、直接向语句直接向视图中插入数据则会报错。视图中插入数据则会报错。INSERT INTO v_dept_emp VALUES(10,ACCOUNTING,2222,TOM); Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器6-3l错误结果如图所示。错误结果如图所示。 Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器6-4l4. 假如我们事先建立了如下所示的假如我们事先建立了如下所示的INSTEAD OF触发器,则不会出错。触发器,则不会出错。lCREATE OR REPLACE TRIGGER tr_v_dept_emp_inf_rowlINST
25、EAD OF INSERTlON v_dept_emplFOR EACH ROWlDECLAREll_temp PLS_INTEGER;lBEGINlSELECT COUNT(*) INTO l_temp FROM dept WHERE deptno=:NEW.deptno;lIF l_temp=0 THENlINSERT INTO dept(deptno,dname) VALUES(:NEW.deptno,:NEW.dname);lEND IF;lSELECT COUNT(*) INTO l_temp FROM emp WHERE empno=:NEW.empno;lIF l_temp=0
26、THENlINSERT INTO emp(empno,ename,deptno)lVALUES(:NEW.empno,:NEW.ename,:NEW.deptno);lEND IF;lEND TRIGGER;l/ Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器6-5l5. 系统提示系统提示“触发器已创建触发器已创建”后,再输入与后,再输入与第第3步相同的步相同的INSERT语句,系统提示语句,系统提示“已创已创建一行建一行”,不再报错。,不再报错。l6. 分别查询视图分别查询视图v_dept_emp和表和表dept、emp的记录,如图所示。的记录,如图所示。 Hand
27、s-On实训教程系列实训教程系列INSTEAD OF触发器触发器6-6l从图中可以看出,视图中多了一条记录。从图中可以看出,视图中多了一条记录。dept表中因为原来就有编号是表中因为原来就有编号是10的部门,因的部门,因此并没有新的数据被添加。表此并没有新的数据被添加。表emp中添加了一中添加了一条记录。实际上,通过条记录。实际上,通过INSTEAD OF触发器,触发器,对视图的操作转化为了对基表的操作。对视图的操作转化为了对基表的操作。 Hands-On实训教程系列实训教程系列DDL触发器触发器4-1 l如果某个表非常重要,不允许被删除,可以创如果某个表非常重要,不允许被删除,可以创建建DD
28、L触发器(触发器(系统触发器系统触发器中的一种)来阻止中的一种)来阻止用户的删除操作。用户的删除操作。l1. 以以SCOTT身份登录到数据库,在身份登录到数据库,在SQL提示提示符下,输入如下的代码来创建一个表符下,输入如下的代码来创建一个表t_test。CREATE TABLE t_test(id NUMBER); l2. 假定这个表不允许被删除,可以输入如下假定这个表不允许被删除,可以输入如下的代码来创建的代码来创建DDL触发器,请注意必须用触发器,请注意必须用BEFORE关键字,不能是关键字,不能是AFTER的。的。 Hands-On实训教程系列实训教程系列DDL触发器触发器4-2l其中
29、的其中的ora_dict_obj_name是系统事件属性是系统事件属性函数,它返回函数,它返回DDL操作所对应的数据库对象名。操作所对应的数据库对象名。lCREATE OR REPLACE TRIGGER tr_t_test_ddllBEFORE DROP ON SCHEMAlBEGINlIF ora_dict_obj_name=T_TEST THEN lRAISE_APPLICATION_ERROR(-20003,表表t_test不允不允许被删除许被删除!);lEND IF;lEND TRIGGER;l/ Hands-On实训教程系列实训教程系列DDL触发器触发器4-3l3. 创建此触发器后
30、,用户如果执行了删除表创建此触发器后,用户如果执行了删除表t_test的操作的操作“DROP TABLE t_test;”,将会,将会出现如图所示的错误,提示表不允许被删除。出现如图所示的错误,提示表不允许被删除。 Hands-On实训教程系列实训教程系列 DDL触发器触发器4-4l4. 以以SYSDBA身份登录到数据库,执行如下的删除身份登录到数据库,执行如下的删除表的操作。表的操作。DROP TABLE scott.t_test;l5. 系统会提示系统会提示“表已删除表已删除”。这是因为上面创建的。这是因为上面创建的触发器是模式级的,即只有在触发器是模式级的,即只有在SCOTT用户模式下,
31、用户模式下,触发器才起作用。如果想让触发器才起作用。如果想让SYSDBA也不能删除表也不能删除表t_test,需要以,需要以SYSDBA身份登录到数据库后,把触身份登录到数据库后,把触发器创建成数据库级的,即在创建触发器代码中把发器创建成数据库级的,即在创建触发器代码中把“SCHEMA”改成改成“DATABASE”。l6. 修改完成后,再试一下第修改完成后,再试一下第4步的删除表的语句,也步的删除表的语句,也将提示将提示“表表t_test不允许被删除不允许被删除”。 Hands-On实训教程系列实训教程系列数据库启动和关闭触发器数据库启动和关闭触发器3-1 l1. 以以SYSDBA身份登录到数
32、据库。身份登录到数据库。l2. 为了记载数据库启动和关闭情况,先创建为了记载数据库启动和关闭情况,先创建一个表一个表t_db_event。lCREATE TABLE t_db_eventl(ltime DATE,levent VARCHAR2(10)l); Hands-On实训教程系列实训教程系列数据库启动和关闭触发器数据库启动和关闭触发器3-2l3. 创建数据库启动触发器。创建数据库启动触发器。l4. 创建数据库关闭触发器。创建数据库关闭触发器。lCREATE OR REPLACE TRIGGER tr_startuplAFTER STARTUP ON DATABASElBEGINlINSE
33、RT INTO t_db_event VALUES(sysdate,STARTUP);lEND; lCREATE OR REPLACE TRIGGER tr_shutdownlBEFORE SHUTDOWN ON DATABASElBEGINlINSERT INTO t_db_event VALUES(sysdate,SHUTDOWN);lEND; Hands-On实训教程系列实训教程系列数据库启动和关闭触发器数据库启动和关闭触发器3-3l5. 用如下的代码,依次关闭和打开数据库。用如下的代码,依次关闭和打开数据库。SQLSHUTDOWN IMMEDIATESQLSTARTUPl6. 用如下的
34、用如下的SELECT语句查询查询语句查询查询t_db_event表的信息。表的信息。SELECT TO_CHAR(time,YYYY-MM-DD HH24:MI:SS) AS ope_time,event FROM t_db_event;l查询结果如图所示。查询结果如图所示。 Hands-On实训教程系列实训教程系列用户登录和退出触发器用户登录和退出触发器4-1 l1. 以以SYSDBA身份登录到数据库。身份登录到数据库。l2. 为了记载用户登录和退出情况,先创为了记载用户登录和退出情况,先创建一个表建一个表t_user_log。lCREATE TABLE t_user_logl(lusern
35、ame VARCHAR(20),ltime_logon DATE,ltime_logoff DATEl); Hands-On实训教程系列实训教程系列用户登录和退出触发器用户登录和退出触发器4-2l3. 创建创建用户登录触发器用户登录触发器。lCREATE OR REPLACE TRIGGER tr_user_logonlAFTER LOGON ON DATABASElBEGINlINSERT INTO t_user_log(username,time_logon) VALUES(user,sysdate);lEND; Hands-On实训教程系列实训教程系列用户登录和退出触发器用户登录和退出触
36、发器4-3l4. 创建用户退出触发器。创建用户退出触发器。lCREATE OR REPLACE TRIGGER tr_user_logofflBEFORE LOGOFF ON DATABASElBEGINlINSERT INTO t_user_log(username,time_logoff) VALUES(user,sysdate);lEND; Hands-On实训教程系列实训教程系列用户登录和退出触发器用户登录和退出触发器4-4l5. 在在SQL提示符下输入如下的代码。提示符下输入如下的代码。CONNECT SCOTT/TIGER;CONNECT / AS SYSDBA;l6. 执行如下的
37、执行如下的SELECT语句查询语句查询t_user_log表的内容。表的内容。lSELECT username,lTO_CHAR(time_logon,YYYY-MM-DD HH24:MI:SS) AS logon_time,lTO_CHAR(time_logoff,YYYY-MM-DD HH24:MI:SS) AS logoff_time lFROM t_user_log; Hands-On实训教程系列实训教程系列管理触发器管理触发器4-1 l1. 以以SCOTT身份登录到数据库。身份登录到数据库。l2. 先用先用DESC语句查看数据字典视图语句查看数据字典视图user_triggers的结
38、构。的结构。DESC user_triggers;l查询结果如图所示。查询结果如图所示。 Hands-On实训教程系列实训教程系列管理触发器管理触发器4-2l3. 用数据字典视图用数据字典视图user_triggers查看基于表查看基于表emp创建的触发器。创建的触发器。l查询的结果如图所示。查询的结果如图所示。lCOLUMN trigger_name FORMAT A16lCOLUMN triggering_event FORMAT A30 lSELECT trigger_name,trigger_type,triggering_event,status FROM user_triggers
39、 WHERE table_name=EMP; Hands-On实训教程系列实训教程系列管理触发器管理触发器4-3l4. 现因工作需要,想把前面所创建的现因工作需要,想把前面所创建的BEFORE行级触发器行级触发器tr_emp_bef_row临时禁临时禁用,可在用,可在SQL提示符下输入如下的语句。提示符下输入如下的语句。ALTER TRIGGER tr_emp_bef_row DISABLE;l5. 系统提示系统提示“触发器已更改触发器已更改”,表明触发器,表明触发器禁用成功。禁用成功。 Hands-On实训教程系列实训教程系列管理触发器管理触发器4-4l6. 把禁用的触发把禁用的触发tr_e
40、mp_bef_row激活,激活,输入如下的代码。输入如下的代码。ALTER TRIGGER tr_emp_bef_row ENABLE;l7. 删除触发器删除触发器tr_emp_bef_row,可在,可在SQL提示符下输入如下的代码。提示符下输入如下的代码。DROP TRIGGERS trigger_name; Hands-On实训教程系列实训教程系列总结总结l触发器是当某一事件发生时自动执行的特殊的触发器是当某一事件发生时自动执行的特殊的过程过程l触发器的作用触发器的作用l触发器的设计原则触发器的设计原则l触发器的组成部分触发器的组成部分l触发器的类型及各种类型触发器的应用触发器的类型及各种
41、类型触发器的应用 Hands-On实训教程系列实训教程系列触发器触发器l触发器是当某一触发器是当某一事件事件发生时发生时自动执行自动执行的的特殊的特殊的过程过程l它与过程的主要区别是:过程是由用户或应用它与过程的主要区别是:过程是由用户或应用程序程序显示调用显示调用的,而触发器不能被直接调用,的,而触发器不能被直接调用,当特定事件(如修改表内数据、删除表或登陆当特定事件(如修改表内数据、删除表或登陆到数据库等)发生时,触发器被到数据库等)发生时,触发器被自动触发自动触发,执,执行事先定义好的行事先定义好的PL/SQL块。块。 Hands-On实训教程系列实训教程系列触发器的作用触发器的作用 l
42、1. 提高数据的安全性。提高数据的安全性。l2. 实现数据审计。实现数据审计。l3. 实现复杂的数据完整性规则。实现复杂的数据完整性规则。l4. 实现复杂的非标准的相关完整性规则。实现复杂的非标准的相关完整性规则。l5. 自动生成数据值。自动生成数据值。 Hands-On实训教程系列实训教程系列触发器的设计原则触发器的设计原则 l1. 当一个操作执行时,为了确保与其相关的其他操当一个操作执行时,为了确保与其相关的其他操作也必须执行时可以使用触发器。作也必须执行时可以使用触发器。l2. 如果能用简单约束(主键、外键、如果能用简单约束(主键、外键、CHECK约束等)约束等)实现的功能不要使用触发器
43、。实现的功能不要使用触发器。l3. 当触发器的代码超过当触发器的代码超过60行或触发器大小超过行或触发器大小超过32KB时,应先建立过程,再在触发器中通过时,应先建立过程,再在触发器中通过CALL语句调语句调用过程。用过程。l4. 不要建立递归触发器。递归触发器是指在触发器不要建立递归触发器。递归触发器是指在触发器中执行的操作,又直接或间接地触发了同一个触发中执行的操作,又直接或间接地触发了同一个触发器。器。 Hands-On实训教程系列实训教程系列触发器的命名触发器的命名 l在同一个用户模式下,触发器不允许重名。在同一个用户模式下,触发器不允许重名。尽管按照规则触发器名可以与其它的数据库尽管
44、按照规则触发器名可以与其它的数据库对象(表、视图等)同名,但不建议这么做。对象(表、视图等)同名,但不建议这么做。 Hands-On实训教程系列实训教程系列触发器的组成部分触发器的组成部分l触发事件触发事件l触发条件触发条件(可选可选)l触发操作触发操作 lCREATE OR REPLACE TRIGGER tr_emp_bef_rowlBEFORE UPDATE OF sallON emplFOR EACH ROWlWHEN (OLD.sal1500)lDECLAREll_scale NUMBER;lBEGINll_scale:=(:NEW.sal-:OLD.sal)/:OLD.sal;lI
45、F l_scale0.1 THENlDBMS_OUTPUT.PUT_LINE(对不起对不起,员工的加薪比例不能超过员工的加薪比例不能超过10%!);l:NEW.sal:=:OLD.sal*1.1;lEND IF;lEND TRIGGER;l/ Hands-On实训教程系列实训教程系列触发器的类型触发器的类型lDML触发器触发器行级触发器行级触发器BEFORE行级触发器行级触发器AFTER行级触发器行级触发器语句级触发器语句级触发器BEFORE语句级触发器语句级触发器AFTER语句级触发器语句级触发器lINSTEAD OF触发器触发器l系统触发器系统触发器DDL触发器触发器数据库启动和关闭触发器
46、数据库启动和关闭触发器用户登录和退出触发器用户登录和退出触发器 Hands-On实训教程系列实训教程系列DML触发器触发器 lDML触发器是指在触发器是指在表表上建立的由上建立的由DML语语句触发的触发器。句触发的触发器。l当在表上执行当在表上执行INSERT、UPDATE或或DELETE等等DML语句时,如果已经建立语句时,如果已经建立了了DML触发器,则触发器中的代码将被触发器,则触发器中的代码将被自动执行。自动执行。l它的触发事件是它的触发事件是DML语句。语句。 Hands-On实训教程系列实训教程系列DML触发器触发器l创建创建DML触发器的语法为:触发器的语法为:lCREATE O
47、R REPLACE TRIGGER trigger_namelBEFORE|AFTERlINSERT|DELETE|UPDATE OF column_listlOR INSERT|DELETE|UPDATE OF column_listlON schema.table_namelREFERENCING NEW AS new_alias OLD AS old_aliaslFOR EACH ROWlWHEN (condition)lPL/SQL Block; Hands-On实训教程系列实训教程系列条件谓词条件谓词l可以在触发器中同时包含多个触发事件,之间用可以在触发器中同时包含多个触发事件,之间
48、用OR关键字隔开。此时在触发器语句中,如有必要,可关键字隔开。此时在触发器语句中,如有必要,可以使用条件谓词以使用条件谓词INSERTING、DELETING和和UPDATING来区分具体的操作类型。来区分具体的操作类型。lINSERTING:当触发事件是:当触发事件是INSERT时,该条件谓时,该条件谓词的返回值是词的返回值是TRUE,否则返回,否则返回FALSE;lDELETING:当触发事件是:当触发事件是DELETE时,该条件谓时,该条件谓词的返回值是词的返回值是TRUE,否则返回,否则返回FALSE;lUPDATING:当触发事件是:当触发事件是UPDATE时,该条件谓时,该条件谓词
49、的返回值是词的返回值是TRUE,否则返回,否则返回FALSE; Hands-On实训教程系列实训教程系列新值和旧值新值和旧值l在行级触发器的语句体中,可以引用在行级触发器的语句体中,可以引用DML语句中涉及的新值语句中涉及的新值和旧值。和旧值。旧值是指在旧值是指在DML语句前存在的数据语句前存在的数据新值是指由新值是指由DML语句插入或更新进去的数据语句插入或更新进去的数据l引用的方式是引用的方式是“:NEW.列名列名”和和“:OLD.列名列名”(注意如果在(注意如果在触发器的触发条件中引用不能加冒号),如果为新行或旧行触发器的触发条件中引用不能加冒号),如果为新行或旧行起了别名,则用别名代替
50、其中的起了别名,则用别名代替其中的NEW或或OLD。l如果触发器是用如果触发器是用INSERT语句触发的,则只能引用新值。语句触发的,则只能引用新值。l如果触发器是用如果触发器是用DELETE语句触发的,则只能引用旧值。语句触发的,则只能引用旧值。l如果触发器是用如果触发器是用UPDATE语句触发的,则既可以引用新值,语句触发的,则既可以引用新值,也可以引用旧值。也可以引用旧值。 Hands-On实训教程系列实训教程系列行级触发器行级触发器l行级触发器是指在执行行级触发器是指在执行DML操作时,操作时,每作用一行就每作用一行就触发一次触发一次的触发器。的触发器。 l行级触发器是触发器中最常用的
51、一种,常用于数据行级触发器是触发器中最常用的一种,常用于数据审计和实现复杂的业务逻辑。审计和实现复杂的业务逻辑。l创建行级触发器时必须加上创建行级触发器时必须加上FOR EACH ROW子句,子句,凡是还凡是还FOR EACH ROW子句的触发器都是行级触发子句的触发器都是行级触发器。器。l按照触发时机的不同,行级触发器可分为:按照触发时机的不同,行级触发器可分为:BEFORE行级触发器行级触发器AFTER行级触发器。行级触发器。 Hands-On实训教程系列实训教程系列BEFORE行级触发器行级触发器 lBEFORE行级触发器指在触发器创建语句中行级触发器指在触发器创建语句中含有含有BEFO
52、RE关键字的行级触发器。关键字的行级触发器。l主要功能:实现约束不能完成的复杂的业务规主要功能:实现约束不能完成的复杂的业务规则和逻辑则和逻辑 l只有在只有在BEFORE行级触发器中才允许重新设行级触发器中才允许重新设置新值置新值 Hands-On实训教程系列实训教程系列AFTER行级触发器行级触发器 lAFTER行级触发器指在触发器创建语句中含行级触发器指在触发器创建语句中含有有AFTER关键字的行级触发器。关键字的行级触发器。l为了审计为了审计DML操作造成的数据变化,可以考操作造成的数据变化,可以考虑使用虑使用AFTER行级触发器。行级触发器。l在使用在使用AFTER行级触发器时,可以引
53、用新值,行级触发器时,可以引用新值,但是不允许重新设置新值。但是不允许重新设置新值。 Hands-On实训教程系列实训教程系列语句级触发器语句级触发器 l语句级触发器在执行语句级触发器在执行DML语句时被自动触发,每个语句时被自动触发,每个DML语句触发一次,即语句触发一次,即无论一个无论一个 DML语句影响了多语句影响了多少行数据,语句级触发器都只执行一次少行数据,语句级触发器都只执行一次。l语句级触发器通常用于审计语句级触发器通常用于审计DML操作和强制实施额操作和强制实施额外的安全措施。外的安全措施。l创建语句级触发器时创建语句级触发器时不能包含不能包含WHEN子句子句。l按照触发时机的
54、不同,语句级触发器可分为两种:按照触发时机的不同,语句级触发器可分为两种:BEFORE语句级触发器语句级触发器AFTER语句级触发器。语句级触发器。 Hands-On实训教程系列实训教程系列BEFORE语句级触发器语句级触发器 lBEFORE语句级触发器指在触发器创建语句语句级触发器指在触发器创建语句中含有中含有BEFORE关键字的语句级触发器。关键字的语句级触发器。 lBEFORE语句级触发器常用于提供额外的安语句级触发器常用于提供额外的安全性措施。全性措施。 Hands-On实训教程系列实训教程系列AFTER语句级触发器语句级触发器 lAFTER语句级触发器指在触发器创语句级触发器指在触发
55、器创建语句中含有建语句中含有AFTER关键字的语句关键字的语句级触发器。级触发器。lAFTER语句级触发器一般用来对语句级触发器一般用来对DML操作进行审计。操作进行审计。 Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器 lINSTEAD OF触发器是在触发器是在视图视图上而非表上定义上而非表上定义的触发器。的触发器。l对于简单的视图,可以直接在视图上执行对于简单的视图,可以直接在视图上执行DML语句而更新基表。但对于复杂的视图,语句而更新基表。但对于复杂的视图,执行执行DML语句则有某些限制(本书专题四中语句则有某些限制(本书专题四中曾有介绍),此时可通过曾有介绍)
56、,此时可通过INSTEAD OF触发器,触发器,用触发器内的语句来代替实际的用触发器内的语句来代替实际的 DML语句,语句,从而允许用户更新本来不能用从而允许用户更新本来不能用DML语句直接语句直接更新的视图。更新的视图。 Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器l使用使用INSTEAD OF触发器,需注意以下几点:触发器,需注意以下几点:lINSTEAD OF触发器触发器只能应用于视图,而不能应用只能应用于视图,而不能应用于表于表lINSTEAD OF触发器触发器只能是行级的只能是行级的,不能是语句级,不能是语句级的,定义的,定义INSTEAD OF触发器时触
57、发器时必须加上必须加上FOR EACH ROW选项。选项。l在在INSTEAD OF触发器触发器不能包含不能包含WHEN子句子句。lINSTEAD OF触发器的定义中触发器的定义中不能包含不能包含BEFORE和和AFTER选项。选项。 Hands-On实训教程系列实训教程系列INSTEAD OF触发器触发器l建立建立INSTEAD OF触发器的语法为:触发器的语法为:lCREATE OR REPLACE TRIGGER trigger_namelINSTEAD OFlINSERT|DELETE|UPDATE OF column_listlOR INSERT|DELETE|UPDATE OF column_listlON schema.view_namelREFER
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论