`

oracle 触发器

阅读更多

 

申明:该文转自小乐乐博客:http://xiaolele.iteye.com

触发器是指存放在数据库中,并被隐藏执行的存储过程。在Oracle8i之前,只允许基于表或视图的DML操作(insert,update,delete)建立触发器,在oracle8i之后,不仅支持DML操作,也允许基于系统事件(启动数据库,关闭数据库,登录)和DDL操作建立触发器。 
一、触发器简介 
   触发器是指隐含执行的存储过程,它可以使用PL/SQL,java和C进行开发,当发生特定事件(例如:修改表、建立对象、登录数据库)时,Oracle会自动执行触发器的相应代码。 
触发器由触发事件、触发条件和触发操作三部分组成。 
1、触发事件 
触发事件是指触发器被触发的SQL、数据库事件和用户事件,在oracle8i之前,触发事件只能是DML操作,在oracle8i之后,不仅支持DML事件,而且还增加了其他事件,具体事件如下:

  • 启动和关闭例程
  • Oracle错误信息
  • 用户登陆和关闭会话
  • 特定表和视图的DML操作
  • DDL语句


2、触发条件(可选) 
触发条件是指使用when子句指定一个boolean表达式,当表达式返回true时,则执行触发器相应代码,如果表达式返回false或unknown,则不会执行触发器相应代码。 
3、触发操作 
触发操作是指包含SQL语句和其他执行代码的PL/SQL块,不仅可以使用PL/SQL开发,也可以使用java或c语言开发,当触发条件为true时,会自动执行触发操作的相应代码。但是在编写触发器执行代码时,需要注意一下限制:

  • 触发代码大小不能超过32k,如果确实需要使用大量代码建立触发器,应该首先建立存储过程,然后在触发器中使用call语句调用存储过程。
  • 触发器代码只能包括insert、update和delete语句,而不能包括DDL语句(create、drop、alert)和事务控制语句(commit,rollback和savepoint)。


二、建立DML触发器 
    当建立DML触发器时,需要指定触发时机(before和after)、触发事件(insert、select、update、delete)、表名、触发类型、触发条件以及触发操作。 
1、触发时机 
  触发时机是指触发器的触发时间,当指定before关键字时,表示在执行DML操作之前触发触发器;当指定after关键字时,表示在执行DML操作之后触发触发器。 
2、触发事件 
触发条件是指被引起触发器执行的DML语句,即insert、update、delete操作。即可以使用单个触发事件,也可以组合多个触发事件。 
3、表名 
因为DML触发器是针对特定表执行的,所以必须指定DML操作所对应的表名。 
4、触发类型 
触发类型用于指定当触发事件发生后,需要执行几次触发操作,如果指定语句触发类型(默认),则只会执行一次触发器代码,如果指定行触发器,则会在每个被作用行上执行一次触发器。 
5、触发条件 
触发条件用于指定执行触发器代码的条件,只有当条件为true时,才会执行触发器代码,当编写DML触发器时,只能在行触发器上执行触发条件。 
6、触发操作 
触发操作用于指定触发器执行的代码,如果使用PL/SQL存储过程、java存储过程或外部存储过程,则在触发操作中使用call语句调用相应过程。如果使用PL/SQL匿名块编写触发操作,则按照以下格式编写。 
[declare] 
  定义变量、常量等。 
begin 
  编写SQL语句或PL/SQL块。 
exception 
  编写例外处理语句。 
end;
 
7、DML触发器触发顺序 
(1)、DML触发器在单行数据上执行顺序 
    对于单行数据而言,无论是语句触发器、还是行触发器,都执行一次,并且执行顺序是 
    before语句触发器、before行触发器、DML操作,after行触发器、after语句触发器。 
(2)、DML触发器在多行数据上执行顺序 
   对于多行数据而言,语句触发器只执行一次,而行触发器则在每个作用行上都执行一次。 
三、语句触发器 
语句触发器是当执行DML语句时被隐含执行的触发器。注意语句触发器时,不能记录列数据的变化。建立语句触发器的语法如下:

Oracle代码   收藏代码
  1. create or replace trigger trigger_name   
  2.    timing event1[or event2 or event3]  
  3.  on table_name  
  4. pl/sql block;  


如上所示:trigger_name用于指定触发器名称,timing用于指定触发时机(before和after),event1用于指定指定触发事件(insert、update、delete),table_name用于指定DML操作对应的表名。 
1、建立before语句触发器 
   为了禁止工作人员在休息日改变雇员信息,可以建立before语句触发器,以实现数据的安全保护,示例如下:

Oracle代码   收藏代码
  1. create or replace trigger trigger_before  
  2. before insert or update or delete on cip_tmps  
  3. begin  
  4.      if to_char(sysdate,'DY','nls_date_language=AMERICAN')  
  5.       IN ('STA','SUN','THU','WED') then  
  6.       raise_application_error(-20001,'不能在周末修改数据');  
  7.       end if;  
  8. end;  


  2、使用条件谓词 
当在触发器中同时包含多个触发时间(insert、update、delete),为了在触发器代码中区分具体的触发事件、可以使用以下三个条件谓词:

  • INSERTING:当触发条件是insert操作时,该条件谓词返回值为true,否则返回值为false。
  • UPDATING:当触发条件是update操作时,该条件谓词返回值为true,否则返回值为false。
  • DELETING:当触发条件是delete操作时,该条件谓词返回值为true,否则返回值为false。


下面示例说明在触发器中使用这三个条件谓词的方法,示例如下:

Oracle代码   收藏代码
  1. create or replace trigger trigger_before  
  2. before insert or update or delete on cip_tmps  
  3. begin  
  4.      if to_char(sysdate,'DY','nls_date_language=AMERICAN')  
  5.       IN ('STA','SUN','THU','WED') then  
  6.       case   
  7.       when inserting then  
  8.         raise_application_error(-20001,'不能在周末添加数据');  
  9.       when updating then  
  10.         raise_application_error(-20002,'不能在周末修改数据');  
  11.       when deleting then  
  12.         raise_application_error(-20003,'不能在周末删除数据');  
  13.         end case;  
  14.       end if;  
  15. end;  


3、建立after语句触发器 
在往cip_temp表中插入数据时,同时往cip_temps表中插入数据,必备条件是,cip_temp表中必须有一个字段标示是最后插入的那条记录。

 
Oracle代码   收藏代码
  1. create or replace trigger trigger_after  
  2. after insert on cip_temp  
  3. begin  
  4. insert into cip_temps (select * from(select * from cip_temp order by id) where rownum=1);  
  5. end;  


四、建立行触发器 
行触发器是指执行DML操作时,每作用一行就触发一次触发器。建立行触发器语法如下:

 
Oracle代码   收藏代码
  1. create or replace trigger trigger_name   
  2.    timing event1[or event2 or event3]  
  3.  on table_name  
  4. [REFERENCING NEW AS NEW | OLD AS OLD]  
  5. for each row  
  6. pl/sql block;  


如上所示:trigger_name用于指定触发器名称,timing用于指定触发时机(before和after),event1用于指定指定触发事件(insert、update、delete),table_name用于指定DML操作对应的表名。REFERENCING 子句用于指定引用新、旧、数据方式,默认情况下使用old修饰符引用旧数据,使用new修饰符是引用新数据。for each row表示建立行触发器。 
1、建立before行触发器 
确保员工工资不能涨价,示例如下:

Oracle代码   收藏代码
  1. create or replace trigger trigger_before_row  
  2. before update on cip_tmp  
  3. for each row  
  4. begin  
  5.   if(:new.id <>:old.id) then  
  6.   raise_application_error(-20001,'员工工资不能调整');  
  7.   end if;  
  8. end;  


2、建立after行触发器 
做到更新、删除、添加一个表中的数据,则另一个表也相应的更新、删除、添加。

Oracle代码   收藏代码
  1. create or replace trigger trigger_after_row  
  2. after insert or update or delete on cip_test  
  3. for each row  
  4. declare  
  5. v_update int;  
  6. v_delete int;  
  7. begin  
  8. case   
  9.   when inserting then  
  10.     insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);  
  11.   when updating then  
  12.       select count(*) into v_update from cip_temps where id=:old.id;  
  13.       if(v_update=0) then  
  14.       insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);  
  15.       else  
  16.             update cip_temps set name=:new.name,age=:new.age,address=:new.address   
  17.             where id=:old.id;  
  18.       end if;  
  19.   when deleting then  
  20.     select count(*) into v_delete from cip_temps where id=:old.id;  
  21.     if(v_delete<>0)then  
  22.      delete from cip_temps where id=:old.id;  
  23.     end if;  
  24.    end case;     
  25. end;  


3、限制行触发器 
当使用行触发器时,默认情况下会作用在每行执行一次触发器,为了在特定条件下执行行触发器代码,就需要使用when子句对触发条件加以限制。 
示例如下:

Sql代码   收藏代码
  1. create or replace trigger trigger_after_row_when     
  2. after  update or delete on cip_test     
  3. for each row     
  4. when (old.name='aa8')     
  5. declare     
  6. v_update int;     
  7. begin     
  8. case      
  9.   when updating then     
  10.       select count(*) into v_update from cip_temps where id=:old.id;     
  11.     if(v_update=0) then     
  12.      insert into cip_temps values(:new.name,:new.age,:new.address,:new.id);     
  13.     else     
  14. update cip_temps set name=:new.name,age=:new.age,address=:new.address where id=:old.id;     
  15.     end if;     
  16.    end case;        
  17. end;    
 4、DML触发器使用注意事项 
当编写DML触发器时,触发器代码不能从触发器所对应的表中读取数据。 
5、实现参照完整性 
参照完整性是指两个表具有主从关系(主外健关系),当删除主表数据时,必须确保相应的从表的数据也被删除,可以在定义外键约束时指定on delete cascade。 
五、行触发器和语句触发器区别 
1、行触发器有 for each row子句。语句触发器没有for each row 子句。 
2、行触发器,可以有 when 作为触发限制,可以使用new/old。语句触发器不能有when 作为触发限制。 
3、行触发器:对应DML语句所影响到的表中的每一行,触发器都要执行一遍。 
4、语句触发:对应DML语句所影响到的表中的所有行,触发器只执行一遍。 
对表进行行级触发的,则该表暂时不能操作(即该表已经成为变异表)表 级触发器与此不同

 

分享到:
评论
1 楼 有你的生命 2012-08-22  
十分详细,很受用,辛苦了

相关推荐

    调试oracle触发器方法

    调试Oracle触发器是开发和维护数据库应用程序时的重要步骤,可以帮助我们找出潜在的错误和逻辑问题。下面我们将详细探讨如何调试Oracle触发器。 1. **PL/SQL Developer工具调试**: - PL/SQL Developer是一款强大...

    oracle 触发器实时调用java 中http接口

    总之,"Oracle触发器实时调用Java中HTTP接口"是一个数据库与应用程序实时通信的示例,涉及Oracle的触发器、存储过程和UTL_HTTP包,以及Java HTTP服务器的设计和实现。这样的设计需要对Oracle PL/SQL和Java网络编程有...

    关于oracle触发器before和after的应用问题

    ### Oracle触发器Before和After应用详解 #### 引言 Oracle数据库系统中,触发器是一项核心功能,用于响应特定事件的自动执行代码块。本文旨在深入解析Oracle触发器中的Before和After两种触发时机,以及它们在...

    Oracle触发器语法详解

    "Oracle触发器语法详解" Oracle 触发器是一种特殊的存储过程,它在插入、删除或修改特定表中的数据时触发执行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。触发器可以基于数据库的值使用户具有操作...

    个人亲测oracle触发器调用java程序

    Oracle触发器调用Java程序 Oracle触发器是Oracle数据库中的一种机制,可以在数据库中执行特定的操作。在本文中,我们将介绍如何使用Oracle触发器调用Java程序。 一、加载Java程序 首先,我们需要将Java程序加载到...

    Oracle触发器与存储过程高级编程-第3版itpub.rar

    《Oracle触发器与存储过程高级编程》第3版是一本深入探讨Oracle数据库中触发器和存储过程技术的专业书籍。在Oracle数据库系统中,触发器和存储过程是数据库管理员和开发人员进行复杂业务逻辑处理和数据管理的重要...

    oracle触发器的创建与使用

    【Oracle触发器的创建与使用】是数据库管理中不可或缺的一部分,尤其在Oracle数据库系统中,触发器扮演着关键角色。触发器是一种存储过程,当特定的数据库事件发生时(如INSERT、UPDATE或DELETE操作),它会被自动...

    Oracle触发器实验报告

    Oracle触发器是数据库管理系统中的一种特殊程序,它与数据库表的操作紧密相关,可以在特定的数据操作事件(如INSERT、UPDATE或DELETE)发生时自动执行。在本实验报告中,主要涉及了Oracle触发器与参照完整性约束的...

    Oracle触发器 实例讲解

    Oracle 触发器实例讲解 Oracle 触发器是一种特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。它主要有以下几个功能: 1. 允许/限制对表的修改:触发器可以控制对表的修改操作,...

    Oracle触发器备份表数据

    在深入探讨如何利用Oracle触发器备份表数据之前,我们首先需要理解几个关键概念:Oracle数据库、触发器以及备份策略。Oracle数据库是全球领先的数据库管理系统之一,以其强大的性能、可靠的安全性和丰富的功能受到...

    Oracle触发器修改自身表

    1、行级触发器不支持 update 、select 、delete 对自身表的操作。 2、表级触发器 不支持 :new 和 :old对象 所以想要触发器对自身表数据做修该,则用行级触发器得到 :new 和 :old对象中的相关数据,然后将这样的数据...

    oracle触发器功能介绍

    Oracle触发器是数据库对象之一,它在特定的数据库操作(如INSERT、UPDATE或DELETE)发生时自动执行。触发器主要用于实现复杂的业务规则和数据验证,它们可以扩展SQL的功能,允许在数据修改前后执行一系列的动作。...

    oracle触发器调用存储过程

    "Oracle触发器调用存储过程" Oracle触发器可以调用存储过程,以实现业务逻辑的自动化执行。然而,在触发器中调用存储过程时,需要注意事务的隔离性,以避免出现锁定和死锁的问题。Oracle自治事务(Autonomous ...

    oracle_触发器的种类和触发事件

    "oracle触发器的种类和触发事件" Oracle触发器是一种特殊的存储过程,它可以在数据库中自动执行一些操作,主要用于实现数据的完整性、数据的安全性和业务逻辑的实现。触发器可以分为四种类型:DML触发器、DDL触发器...

    oracle触发器语法要点

    ### Oracle触发器语法要点 #### 一、触发器概述 Oracle触发器是一种存储过程,它在特定的数据库事件(如INSERT、UPDATE或DELETE)发生时自动执行。触发器可以用于实施复杂的业务规则、数据完整性检查或者自动生成...

    oracle触发器执行顺序.pdf

    Oracle触发器可以响应数据表的DML(数据操纵语言)事件,如INSERT、UPDATE或DELETE,也可以响应DDL(数据定义语言)事件,如CREATE、ALTER或DROP等。在本文件中,主要讨论的是针对数据表UPDATE操作的触发器执行顺序...

    oracle触发器与存储过程高级编程

    本节将深入探讨“Oracle触发器与存储过程高级编程”的相关知识。 **触发器(Triggers)** 触发器是一种数据库对象,它在特定的数据库事件(如INSERT、UPDATE或DELETE)发生时自动执行。通过定义触发器,我们可以...

    oracle触发器

    ### Oracle触发器详解 在Oracle数据库管理中,触发器是一种非常强大的工具,它允许你在特定的数据库事件(如数据插入、更新或删除)发生时自动执行预定义的SQL语句或PL/SQL代码块。这使得数据库能够在无需外部程序...

    Oracle触发器里调用Java程序

    本篇文章将探讨如何在Oracle触发器中调用Java程序,以扩展数据库的功能并利用Java丰富的库资源。 首先,我们需要了解Oracle的PL/SQL(Procedural Language/Structured Query Language)语言,它是Oracle数据库内置...

    Oracle触发器与存储过程高级编程

    在深入探讨《Oracle触发器与存储过程高级编程》这一主题之前,我们首先应当明确Oracle数据库在企业级应用中的核心地位。Oracle数据库以其强大的数据处理能力、高可用性和安全性,成为众多大型企业和组织首选的数据...

Global site tag (gtag.js) - Google Analytics