创建触发器

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

    注意:这里说的delete是指不带where子句的delete语句 相同点 truncate和不带where子句的delete, 以及drop都会删除表内的数据 不同点: 1. truncate和 d ...

  2. 利用HTML5开发Android(4)---HTML5本地存储之Web Storage

    Web Storage是HTML5引入的一个非常重要的功能,可以在客户端本地存储数据,类似HTML4的cookie,但可实现功能要比cookie强大的多,cookie大小被限制在4KB,Web Sto ...

  3. MFC中 Invalidate() , InvalidateRect() , UpdateWindow(), Redrawwindow() 区别

    1. void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效.窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口 ...

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

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

  5. Java工具类 Apache Commons:commons-lang

    Commons Lang The standard Java libraries fail to provide enough methods for manipulation of its core ...

  6. js页面文字选中后分享到新浪微博实现

    demo您可以狠狠地点击这里:js文字选中分享到新浪微博demo 方法与代码 选中即分享的功能看上去比较高级,其实实现是相当简单的.其中的会让人头大,一般人也不感兴趣的原理这里就直接跳过.这个js文字 ...

  7. PhoneGap+jQuery Mobile+Rest 访问远程数据

    最近研究Mobile Web技术.发现了一个好东西-PhoneGap! 发现用PhoneGap+jQuery Mobile是一个很完美的组合! 本实例通俗易懂.适合广大开发人群:高富帅.白富美.矮穷戳 ...

  8. [MySQL复制异常]'Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT.'

    MySQL复制错误]Last_Errno: 1666 Last_Error: Error executing row event: 'Cannot execute statement: imposs ...

  9. AIM Tech Round (Div. 2) D. Array GCD dp

    D. Array GCD 题目连接: http://codeforces.com/contest/624/problem/D Description You are given array ai of ...

  10. C#中Thread类中Join方法的理解(转载)

    指在一线程里面调用另一线程join方法时,表示将本线程阻塞直至另一线程终止时再执行      比如 using System; namespace TestThreadJoin { class Pro ...