热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

oraclePL/SQL(procedurelanguage/SQL)程序设计之触发器(trigger)

创建触发器触发器类似于过程和函数,都拥有声明、执行和异常处理过程的带名PLSQL块。与包类似,触发器必须存储在数据库中。前面已经讲过,过程

创建触发器

触发器类似于过程和函数,都拥有声明、执行和异常处理过程的带名PL/SQL块。与包类似,触发器必须存储在数据库中。
前面已经讲过,过程是显式地通过过程调用执行的,同时过程调用可以传递参数。与之相反,触发器是在事件发生时隐式地运行的,并且触发器不能接受参数。
运行触发器的方式叫做激发(firing)触发器。
触发事件可以是对数据库表的DML(INSERT、UPDATE、DELETE)操作或某种视图的操作。Oracle8i把触发器功能扩展到了可以激发系统事件,如数据库的启动和关闭,以及某种DDL操作。
触发器主要分为:DML触发器、替代触发器和系统触发器。本次课程主要讲述DML触发器。
触发器可用来补充声明的参照完整性,强制实施复杂的业务规则。
触发器是一个独立的事务,被当作一个整体执行,在执行过程中如果发生错误,则整个事务会自动回滚。  


DML触发器由DML(INSERT、UPDATE、DELETE)语句激发。
创建DML触发器语法:
CREATE [OR REPLACE] TRIGGER trigger_name
   {BEFORE | AFTER} triggering_event ON table_reference
   [FOR EACH ROW [WHEN trigger_condition]]
trigger_body;
trigger_name是触发器名,triggering_event指定了何时激发触发器, table_reference是定义触发器的表, trigger_body是触发器的主要处理代码。WHEN子句的trigger_condition如果被使用的话,将首先进行求值。触发器的主体仅当此条件求值为TRUE时才被执行

触发器的激发顺序
执行BEFORE语句级触发器(如果有的话)。
对于受语句影响的每一行:
执行BRFORE行级触发器(如果有的话)。(for each row)
执行DML语句
执行AFTER行级触发器(如果有的话)。
执行AFTER语句级触发器(如果有的话)。



实例

CREATE OR REPLACE TRIGGER tri_emp_stmBefore
BEFORE INSERT  ON EMP
BEGIN
  dbms_output.put_line('Before Statement trigger');
END;
CREATE OR REPLACE TRIGGER tri_emp_stmAfter
after INSERT  ON EMP
BEGIN
  dbms_output.put_line('After Statement trigger');
END;


CREATE OR REPLACE TRIGGER tri_emp_rowBefore
before INSERT  ON EMP
for each row
BEGIN
  dbms_output.put_line('Beore row trigger');
END;
CREATE OR REPLACE TRIGGER tri_emp_rowAfter
after INSERT  ON EMP
for each row
BEGIN
  dbms_output.put_line('After row trigger');
END;


创建语句级触发器: Example
CREATE OR REPLACE TRIGGER secure_emp
   BEFORE INSERT ON emp
   BEGIN
     IF (TO_CHAR(SYSDATE, 'DY') IN ('星期六', '星期天'))
           OR (TO_CHAR(SYSDATE, 'HH24:MI') NOT BETWEEN '08:00' AND '18:00')
     THEN
         RAISE_APPLICATION_ERROR (-20500, 'You may insert into EMP table only during business hours.');
      END IF;
END;
创建语句级触发器: 测试上述触发器
SQL>INSERT INTO emp (empno, ename,hiredate,job, sal, deptno)
               VALUES (300,'Smith Rob',SYSDATE,'IT_PROG', 4500, 60)
创建行级触发器: Example
CREATE OR REPLACE TRIGGER restrict_salary
  BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW
    BEGIN
      IF NOT (:NEW.job IN ('AD_PRES', 'AD_VP')) AND :NEW.sal > 15000
      THEN
        RAISE_APPLICATION_ERROR (-20202, 'Employee cannot earn this amount');
      END IF;
END;
创建行级触发器: 测试上述触发器
SQL> UPDATE emp
              SET sal = 15500
              WHERE ename = 'SMITH';


在行级触发器中使用 :old和 :new
触发语句所处理的每一行都激发一次行级触发器。在触发器的内部,你可以访问当前正在被处理的行。这是通过“伪记录”——:old和:new实现的。它们的类型是table_reference%ROWTYPE

在行级触发器中使用 :old和 :new
create or replace TRIGGER GenerateStudentID
  BEFORE INSERT  ON t_student
  FOR EACH ROW
BEGIN
   SELECT seq_student_id.NEXTVAL
      INTO :new.n_student_ID
      FROM dual;
END GenerateStudentID;
执行上述触发器
SQL>INSERT INTO students (first_name, last_name)
  VALUES ('Lolita', 'Lazarus');
SQL>INSERT INTO students (ID, first_name, last_name)
  VALUES (-7, 'Zelda', 'Zoom');



在行级触发器中使用限制条件


创建替代触发器
替代触发器只能定义在视图上

CREATE [OR REPLACE] TRIGGER trigger_name
   INSTEAD OF
       event1 [OR event2 OR event3]
       ON view_name
    [REFERENCING OLD AS old | NEW AS new]
[FOR EACH ROW]
trigger_body

实例
CREATE TABLE new_emps AS
      SELECT empno, ename, sal, deptno, job, hiredate  FROM emp;
CREATE TABLE new_depts AS
     SELECT d.deptno, d.dname, d.loc,sum(e.sal) tot_dept_sal
          FROM emp e, dept d
         WHERE e.deptno = d.deptno
         GROUP BY d.deptno, d.dname, d.loc;
CREATE VIEW emp_details AS
     SELECT e.empno, e.ename, e.sal, e.deptno,e.job, d.dname, d.loc
          FROM emp e, dept d
          WHERE e.deptno = d.deptno;


管理触发器()

删除触发器    DROP TRIGGER secure_emp;

 

 

 

 

 

 

 

转:https://www.cnblogs.com/pacoson/p/3523477.html



推荐阅读
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • 本文主要复习了数据库的一些知识点,包括环境变量设置、表之间的引用关系等。同时介绍了一些常用的数据库命令及其使用方法,如创建数据库、查看已存在的数据库、切换数据库、创建表等操作。通过本文的学习,可以加深对数据库的理解和应用能力。 ... [详细]
author-avatar
半邪书生66_516
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有