创建触发器

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

    一. 相同之处        1.均是可变字符序列,可以随机的改变字符串,如追加操作或插入操作 2. 均使用了内部缓冲区,并且当内部缓冲区溢出后均会自动增大 二. 不同之处       1. Stri ...

  2. spring事物配置注意事项

    <tx:advice id="txAdvice" transaction-manager="transactionManager">  <tx ...

  3. [添加用户]解决useradd 用户后没有添加用户Home目录的情况,Linux改变文件或目录的访问权限命令,linux修改用户密码

    将nobody用户添加到nogroup 组:usermod -g nogroup nobody cat /etc/passwd|grep nobodynobody:x:65534:65534:nobo ...

  4. Oracle中wm_concat()函数的使用

    Oracle中wm_concat()函数的使用 wm_concat()函数是oracle行列转换函数,该函数可以把列值以‘,’分割开来,并显示成一行. 1.原数据: 2.把结果分组以‘|’分隔,以一行 ...

  5. Oracle中TO_DATE格式

    转自:http://www.cnblogs.com/ajian/archive/2009/03/25/1421063.html TO_DATE格式(以时间:2007-11-02   13:45:25为 ...

  6. openNebula 模板实例化成虚拟机【参数名为VM_NAME】

    { "action": { "perform": "instantiate", "params": { "vm ...

  7. 常见错误:Apple Mach-O Linker Error

    常见错误描述: Apple Mach-O Linker Error这类错误的错误信息最后一行通常如下: Command /Developer/Platforms/iPhoneOS.platform/D ...

  8. Cortex-M3 Context Switching

    http://www.embedded.com/design/embedded/4231326/Taking-advantage-of-the-Cortex-M3-s-pre-emptive-cont ...

  9. SaundProgressBar

    https://github.com/eltld/SaundProgressBar

  10. [AngularJS] Accessing Data in HTML -- controllerAs, using promises

    <!DOCTYPE html> <html> <head> <title>Access Data From HTML</title> < ...