码迷,mamicode.com
首页 > 数据库 > 详细

Oracle中触发器(1)

时间:2015-08-06 18:44:00      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:oracle   trigger   触发器   审计   

Oracle数据库触发器是存储于数据库的命名PL/SQL语句块,当触发事件发生时他们会隐含的执行,执行触发器的活动被称为触发触发器。

特定用户在特定模式下,或者任何用户执行的ddl语句(如create或者alter),这种触发器经常被用于审计目的,并且专用于oracle DBA。可以记录各种模式修改,何时执行、以及那个用户执行的。

系统事件,如数据库启动或者关闭

用户事件,如登录或者注销。即可以定义一个触发器,在用户登录数据库时记录用户名和登录时间。

触发器相关视图:

创建触发器的通用语法:

create [or replace] trigger trigger_name
{before|after} triggering_event on table_name
[for each row]
[follows another_trigger]
[enable/disable]
[when condition]
declare
 declaration statements
exception
exception-bandling statements
end ;

triggering_event 是针对数据库表的dml语句,table_name是与该触发器相关的数据库表的名称,子句for each row指定行触发器,只适用于所插入、修改或者删除的数行。when子句指定执行触发器时必须要满足的条件。 触发器的这部分称为触发器的头。

子句follows、enable、disable,它们是在oracle 11g的create or replace trigger

子句中加入的。在11之前需要使用alter trigger 命令来启用或者禁用触发器。

enable/disable子句指定触发器是在启用,还是禁用状态下被创建的。当触发器

被启用时,触发事件发生就会执行该触发器,类似的,当触发器被禁用时,触发

事件发生时也不会执行该触发器。

注意在默认情况下,不使用enable/disable子句创建触发器时,默认是启用的。

alter trigger trigger_name disable ;
alter trigger trigger_name enable ;


使用follows选项,可以指定触发器被触发的顺序,这个选项适用于在相同表上所定义的,并且在相同时间点会执行的触发器。例如,如果在student表上定义两个触发器,并且在数据插入之前触发,如果自己不使用follows子句来指定执行顺序,oracle无法保证这些触发器始终按照相同的次序执行,注意,follows子句中所引用的触发器必须已经存在,并且编译成功。

注意:如果删除一个表,则在该表上所定义的数据库触发器也会被删除。


触发器可以被用于不同的目的:

1.执行不能通过使用完整性约束来定义的复杂业务规则

2.维护复杂的安全规则

3.自动生成衍生列的值

4.手机有关访问数据库表的统计信息

5.防止无效的事务

6.提供值审计


触发器的限制

1.触发器也许不会执行事务控制语句,例如commit、savepoint、rollback。当

触发器执行时,所有执行的操作会成为事务的一部分。当该事务被提交或者回滚

,触发器所执行的操作也会被提交或者回滚。这个规则的一个例外是包含自治事

务的触发器。

2.触发器调用的任何函数或者过程也许不会执行事务控制语句,除非包含自治事务

3.不允许在触发器体中声明long或者long raw变量


触发器的分类:before触发器和after触发器

before触发器

create or replace trigger student_bi
before insert on student
for each row
declare
v_student_id student.student_in%type ;
begin 
  select student_id_seq.nextval
   into v_student_id
   from dual ;
  :new.student_id := v_student_id ;
  :new.created_by := user ;
  :new.created_date := sysdate ;
  :new.modified_by := user ;
  :new.mocified_date := sysdate ;
end ;

触发器包含伪记录:new,使得可以访问当前正在被处理的数据行,也就是说当前被插入student表的数据行。:new伪记录是一种triggering_table%type,所以在在当前情况下,它是student%type类型,为了访问伪记录:new的单独成员,需要使用点符号,也就是:new.created_by指的是:new伪记录的成员created_by,记录名和其成员之间使用点符号。

把序列值赋予student_id列的语句,通过pl/sql表达式访问序列是11G的新特性

在11G之前,只能通过查询访问序列。



如下情况,应该使用before触发器

1.当在insert或者update语句完成之前,触发器需要提供衍生列的值是。

  如,enrollment表中final_grade列保存学生特定课程的最终成绩,这个值

  来自于学生在整个课程期间的综合表现

2.当触发器决定insert、update或者delete语句是否应该允许完成的时候,如

  当往instructor表插入一条记录,触发器可以验证给zip列提供的值是否有效,

  或者也就是说,zipcode中是否存在对应整个值的记录


AFTER触发器

一个statistics表的结构如下所示

 Name					   Null?    Type
 ----------------------------------------- -------- ----------------------------
 TABLE_NAME					    VARCHAR2(30)
 TRANSACTION_NAME				    VARCHAR2(10)
 TRANSACTION_USER				    VARCHAR2(30)
 TRANSACTION_DATE				    DATE


整个表用来收集数据库中不同表的统计信息,例如,可以记录谁从instractor表删除记录,以及删除的时间。

create or replace trigger instructor_aud
  after update or delete on instructor
declare
  v_type varchar2(10);

begin
  if updating then
    v_type := ‘UPDATE‘;
  
  elsif deleting then
    v_type := ‘DELETE‘;
  end if;

  update statistics
     set transaction_user = user, transaction_date = sysdate
   where table_name = ‘instructor‘
     and transaction_name = v_type;

  if sql%notfound%type then
    insert into statistics values (‘instructor‘, v_type, user, sysdate);
  end if;

end;

例子针对表instructor,触发器会在表update或者delete语句执行之后触发。

如下情况,应该使用after触发器

1.当触发器应该在dml语句执行之后被触发时。

2.当触发器执行before触发器中未指明的动作时。

详细操作见下篇.....

本文出自 “相守姑娘说” 博客,请务必保留此出处http://sugarlovecxq.blog.51cto.com/6707742/1682287

Oracle中触发器(1)

标签:oracle   trigger   触发器   审计   

原文地址:http://sugarlovecxq.blog.51cto.com/6707742/1682287

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!