创建触发器

触发器类似于过程和函数,都拥有声明、执行和异常处理过程的带名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;

oracle PL/SQL(procedure language/SQL)程序设计之触发器(trigger)的更多相关文章

  1. oracle PL/SQL(procedure language/SQL)程序设计

    PL/SQL(procedure language/SQL)语言是Oracle对SQL语言的过程化扩充,是一个完整的编程语言.PL/SQL实现了过程化语句(如分支.循环等)与SQL语句的无缝连接,将过 ...

  2. Oracle笔记--PL/SQL(Procedure Language & Structured Query Language)

    1.PL/SQL是一种高级数据库程序设计语言,专门用于在各种环境下对Oracle数据库进行访问.该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理. 2.PL/SQL是对SQ ...

  3. oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)

    什么是异常?在PL/SQL中的一个标识.在程序运行期间被触发的错误.异常是怎样被触发的?产生一个Oracle错误.用户显示触发.怎样处理异常?用异常处理句柄捕获异常.传播异常到调用环境. 捕获异常 E ...

  4. oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包

    匿名PL/SQL块回顾 DECLARE (可选)    定义在PL/SQL块中要使用的对象BEGIN (必须)    执行语句EXCEPTION (可选)    错误处理语句END; (必须)匿名块( ...

  5. oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包(转)

    匿名PL/SQL块回顾 DECLARE (可选)     定义在PL/SQL块中要使用的对象 BEGIN (必须)     执行语句 EXCEPTION (可选)     错误处理语句 END; (必 ...

  6. oracle PL/SQL(procedure language/SQL)程序设计之游标cursors

    游标 Cursors--Conception 每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SE ...

  7. oracle PL/SQL(procedure language/SQL)程序设计(在PL/SQL中使用SQL)

    在PL/SQL程序中,允许使用的SQL语句只有DML和事务控制语句,使用DDL语句是非法的.使用SELECT语句从数据库中选取数据时,只能返回一行数据.使用COMMIT,  ROLLBACK, 和SA ...

  8. oracle PL/SQL(procedure language/SQL)程序设计--控制结构(if else )

    IF逻辑结构:IF-THEN-END IFIF-THEN-ELSE-END IFIF-THEN-ELSIF-END IF 语法 IF condition THEN  statements;[ELSIF ...

  9. oracle PL/SQL(procedure language/SQL)程序设计(续集)之PL/SQL函数

    PL/SQL函数 examples:“ 构造一个邮件地址 v_mailing_address := v_name||CHR(10)||                                 ...

随机推荐

  1. [网络]远程访问局域网svn服务器[转]

    转至:http://8474832.blog.51cto.com/8464832/1555449 打开路由器访问界面 选择转发规则->端口映射-新建 在弹出的界面中填写相应的端口号了内网ip 填 ...

  2. jquery操作select 的value和text值

    获取select 的text值: $('#testSelect option:selected').text(); 获取select 的value值: $('#testSelect').val(); ...

  3. Unity中的C#规则

    命名 文件名和Class要一致(CamelCase) 类公共和保护类型Property(CamelCase) 类的公共和保护类型Fields(CamelCase)* 先采用.Net的命名方法,如果出现 ...

  4. VS2010 远程调试

    1.在客户端电脑建一个账户,账户名和密码和调试端的账户密码一样 2.在客户端电脑进入 管理工具-本地安全策略-本地策略-安全选项 网络访问:本地账户的共享和安全模式”,改为“经典-本地用户以自己的身份 ...

  5. (C#)使用队列(Queue)解决简单的并发问题

    (C#)使用队列(Queue)解决简单的并发问题 2015-07-16 13:04 13265人阅读 评论(8) 收藏 举报  分类: Asp.Net(8)  版权声明:本文为博主原创文章,未经博主允 ...

  6. 测试rest接口的两个工具使用详解(restclient+soapUI)

    http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/31/3110764.html http://www.oschina.net/news/618 ...

  7. (剑指Offer)面试题19:二叉树的镜像

    题目: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树的定义如下: struct TreeNode{ int val; TreeNode* left; TreeNode* right; }; 输 ...

  8. C++运算符重载的规则

    运算符重载的规则如下: 1.C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已经有的运算符. 2.重载之后运算符的优先级和结合性都不会改变 3.运算符重载是针对新类型数据的实际需要 ...

  9. Jquery 右键菜单(ContextMenu)插件使用记录

    目前做的项目需要在页面里面用右键菜单,在网上找到两种jquery的右键菜单插件,但是都有各种问题.所以就自己动手把两种插件结合了下. 修改后的右键菜单插架可以根据绑定的触发页面元素不同,复用同一个菜单 ...

  10. php计算脚本执行时间

    利用PHP的microtime实现 function getCurrentTime () { list ($msec, $sec) = explode(" ", microtime ...