设为首页 收藏本站
查看: 840|回复: 0

[经验分享] Oracle中触发器(1)

[复制链接]

尚未签到

发表于 2018-9-9 10:14:33 | 显示全部楼层 |阅读模式
  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触发器中未指明的动作时。
  触发器类型
  行级触发器和语句级触发器
  instead of触发器
  行级触发器指的是触发器被触发的次数等同于触发语句所影响的数据行数量。当
  语句for each row出现在create trigger中时,该触发器就是行级触发器。
  语句级触发器
  没执行一次,触发器就会执行一次,不管触发语句影响多少数据行
  详细操作见下篇.....



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-568609-1-1.html 上篇帖子: Oracle学习之DATAGUARD(八) Switchover与failover 下篇帖子: Oracle学习之DATAGUARD(九) 自动Failover
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表