ORACLE 第九讲 触发器
本章目标 熟练掌握行级触发器的创建和使用 熟练掌握语句级触发器的创建和使用 熟练掌握替代触发器的创建和使用
触发器 什么是触发器 触发器是当特定事件出现时自动执行的代码块。 触发器与过程的区别在于:过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的。Oracle会在事件请求发生时,执行适当的触发器。
触发器 创建触发器 Create or replace trigger <触发器名> before | after | instead of --指定是在完成操作前还是操作后触发触发器 Insert [or delete] [or update] of <列名> on <表名|视图名> [ REFERENCING [ NEW AS new_row_name ] [ OLD AS old_row_name ] ] –给new或者old定义一个别名,在下面的程序中用别名代替new或者old使用 [for each row] --指定每行触发一次,默认情况下,数据库触发器每个表触发一次 [When (<条件>)] declare ------ Begin -------- exception End;
触发器 举例:在 SCOTT模式的EMP表上创建触发器。 create or replace trigger c_emp_deptno before insert or update of deptno on emp for each row when (new.deptno<>40) begin :new.comm:=0; end;
触发器 触发器的组成 触发器语句 触发器条件 触发器操作
触发器 触发器的组成 触发器语句 触发器语句是那些可以导致触发器的事件,即在表和视图上实行的INSERT、DELETE、UPDATE之类的DML语句,在模式对象上执行的DDL语句或数据库事件。 before insert or update of deptno on emp for each row 这就是说,触发器会在这些事件之前隐式执行;当对EMP表执行INSERT语句或对EMP表的deptno列进行UPDATE 时。而且触发器将在受到影响的每一行上执行一次。但是触发器是否真正执行还要检查触发器限制条件,只有满足限制条件才会执行。
触发器 触发器的组成 触发器条件 触发器限制条件包含一个布尔表达式,该值必须为“真”才能激活触发器。如果该值为“假”或“未知”,将不运行出发操作。 when (new.deptno<>40) 这就是说,如果列deptno的新值不等于40,触发器就会执行。
触发器 触发器的组成 触发器操作 触发器操作是触发器的主体,包含一些SQL语句和代码,这些代码在执行触发器语句且触发器限制条件的值为“真”时运行。行级触发器允许出发操作中的语句访问行的列值。 begin :new.comm:=0; end; 这段代码将列comm新值设为0。
触发器 举例:测试创建的触发器是否有效 insert into values (8000,'Philip','MANAGER',null,'31-12月-2002',6000,500,30); insert into values (8001,'Tom','MANAGER',null,'31-12月-2002',6000,500,40); commit; 上述语句在EMP表中插入了两条记录,并为每行记录指定了 COMM列的值。用户在表中插入了值,这将激活前面创建的触发器。
触发器 触发器的类型 行级触发器 行级触发器对DML语句影响的每个行执行一次。例如, UPDATE语句影响多行,就会对每行都激活一次行触发器。行级触发器是触发器中最常用的一种,通常用于数据库审计和实现复杂的业务逻辑。可以在CREATE TRIGGER命令中指定FOR EACH ROW子句创建行级触发器。 由于触发器是事件驱动的,因此可以设置触发器在这些事件之前或者之后执行,即在执行DML语句之前或之后执行。在触发器中,可以引用DML语句中涉及的旧值或新值。“旧”是指在DML语句之前存在的数据。UPDATE和DELETE通常引用旧值。“新”是指由DML语句创建的数据值(如插入记录中的列)。 如果需要通过触发器在插入行中设置一个列值,就应该使用BEFORE INSERT触发器访问“新”值。使用AFTER INSERT触发器不允许设置插入值,因为该行已经插入表中。 在审计应用程序中经常使用AFTER行级触发器,直到行被修改才会触发它们。行的成功修改表明此行已经通过该表定义的完整性约束。 行级触发器的执行谓词: Insert Delete update
触发器 触发器的类型 行级触发器 举例:创建行级触发器,跟踪触发事件前后表中值的变化 举例:利用触发器和序列实现自增序列. 举例:当把某一部门从dept表删除后,就删除emp表中的该部门的所有信息。 举例:库存-出货
触发器 触发器的类型 表级触发器(语句级触发器) 表级触发器对每个DML语句执行一次。例如,如果一条INSERT语句在表中插入200行,那么这个表上的INSERT表级触发器只执行一次。表级触发器不常用于数据相关的活动,通常用于强制实施在表上执行操作的额外安全措施。表级触发器是CREATE TRIGGER命令创建的触发器的默认类型。 执行谓词: Inserting Deleting Updating 举例:创建一个表级触发器,跟踪DML操作(一次删除或修改一条和多条)
触发器 触发器的类型 表Instead of触发器(替代触发器) 使用INSTEAD OF触发器的限制: 创建语法: INSTEAD OF触发器是在视图上而不是在表上定义的触发器,它是用来替换所使用实际语句的触发器。这样的触发器可以用于克服Oracle在任何视图上设置的限制,允许用户修改不能直接使用DML语句修改的视图。 使用INSTEAD OF触发器的限制: 它们只能在行级使用,而不能在语句级使用。 它们只能应用于视图,而不能应用于表。 如果有需要同时向两个表中插入值的情况,可以通过INSTEAD OF触发器来实现。 创建语法: CREATE TRIGGER <触发器名> INSTEAD OF INSERT|UPDATE|DELETE ON 视图名 BEGIN …… END; 举例:创建一个替代触发器.student,subject,score
触发器 创建触发器的限制 主体中 可以包括“DML SQL”语句,但“SELECT”语句必须为“SELECT INTO”语句或必须在游标声名中; 触发器的主体中不允许有DDL声名; 不允许有事务控制语句(COMMIT、ROLLBACK、SAVEPIONT); 如果所存储的子程序被触发器调用,则它不能包括TCL.
触发器 触发器的启用和禁用 可以启用也可以禁用触发器。默认情况下,所有触发器在首次创建时就是启用的。 ALTER TRIGGER <触发器名> DISABLE; ALTER TRIGGER <表名> DISABLE ALL TRIGGERS; ALTER TRIGGER <触发器名> ENABLE; ALTER TRIGGER <表名> ENABLE ALL TRIGGERS;
触发器 删除触发器 语法: DROP TRIGGER <触发器名>;