日期:2014-05-16  浏览次数:20377 次

oracle学习---触发器
触发器:
◆ 是一个PL/SQL快或者是与表,试图方案或数据库关联的PL/SQL过程
◆ 当特定的事件发生时隐式执行
触发器可以是:
◆ 应用程序触发器:当特定的应用程序的事件发生时触发
◆ 数据库触发器:当数据事件(DML)在一个方案上发生或系统事件(例如:登录或关闭数据库)在数据库上发生时触发
    使用触发器的原则:
◆ 创建存储过程并且在触发器中调用它们,如果PL/SQL 代码非常长。
◆ 过分地使用触发器可能导致复杂的依赖,这在大的应用程序中可能会产生维护困难。
   触发器包含:
◆ 触发时间(表:BEFORE,AFTER.试图:INSTEAD OF)
◆ 触发事件(INSERT,UPDATE,DELETE)
◆ 触发类型(ROW,STATEMENT)
◆ 触发器体(PL/SQL块)
   数据库触发器:
        在写触发器代码之前,确定触发器各部分的值:触发时机、触发事件和触发类型。
       
部分 说明 可能值
触发器时机
当触发器涉及的触发事件时的触发时机 BEFORE、AFTER 、INSTEAD OF
触发事件 在表或视图上的哪一个数据操纵操作引发了触发器触发 INSERT、UPDATE、DELETE
触发器类型 触发器体被执行多少次 Statement、Row
触发器体 触发器执行的那些动作 PL/SQL 块
如果在一个表上定义了多个触发器,要意识到相同类型的多个触发器的触发顺序是随机的。为了保证相同类型的多个触发器以特定的顺序触发,统一多个触发器到一个触发器中,再以想要的顺序分别调用过程。
? BEFORE:在表上触发DML事件之前执行触发器体。
? AFTER: 在表上触发DML事件之后执行触发器体。
? INSTEAD OF:执行触发器体代替触发语句。用于不能以别的方式修改的视图。
触发器类型:触发器体将对语句影响的每行都执行,还是只执行一次?
语句:触发器体对于触发事件执行一次,这是默认。一个语句触发器触发一次,即使根本没有行受影响。
? 行:触发体对受触发事件影响的每行执行一次。如果触发事件没有受影响的行,行触      发器不执行。
触发器体:触发器将执行的哪些动作?触发器体是一个PL/SQL 块或对一个过程的调用。
? 触发器动作定义那些再触发事件被发布时需要被做的事情。 PL/SQL 块可以包含 SQL 和 PL/SQL 语句,并且可以定义变量、光标、表达式等 PL/SQL 结构。你也可以调用一个 PL/SQL 过程或一个 Java 过程。
? 另外,行触发器用相关的名字来访问由触发器处理的行的 old 和 new 列值。
? 注:触发器的大小不能超过 32 K。
定义触发器:
   
 CREATE OR REPLACE TRIGGER trigger_name
Timing event1[OR event2OR event3]
ON table_name
Trigger_body
举例1:
   
CREATE OR REPLACE TRIGGER secure_person
BEFORE INSERT ON person
BEGIN
IF (TO_CHAR(SYSDATE,’DY’) IN (’SAT’,’SUN’)) OR
       (TO_CHAR(SYSDATE,’HH24:MI’)
        NOT BETWEEN ’08:00’AND ’18:00’) THEN 
      RAISE_APPLICATION_ERROR (-20500,’You may insert 
      into personS table onlyduring business hours.’);
END IF;
END;
/ 
举例2:
  
CREATE OR REPLACE TRIGGER secure_person 
BEFORE INSERT OR UPDATE OR DELETE ON person
BEGIN
IF (TO_CHAR (SYSDATE,’DY’) IN (’SAT’,’SUN’))
      OR(TO_CHAR (SYSDATE, ’HH24’) 
NOT BETWEEN ’08’AND ’18’)THEN
   IF DELETING THEN
         RAISE_APPLICATION_ERROR (-20502,’You may delete from
                person table only during business hours.’);
   ELSIF INSERTING THEN
         RAISE_APPLICATION_ERROR (-20500,’You may insert into
                person table only during business hours.’);
   ELSIF UPDATING (‘SALARY’) THEN 
         RAISE_APPLICATION_ERROR (-20503,’You may update SALARY 
               only during business hours.’);
   ELSE RAISE_APPLICATION_ERROR (-20504,’You may 
         Update person table only during normal hours.’);
   END IF;
END IF;
END; 
/

行触发器:
  
CREATE[OR REPLACE] TRIGGER trigger_name 
    timing  event1 [OR event2 OR event3]
      ON table_name
   [REFERENCING OLD AS old| NEW AS new]
FOR EACH ROW
[WHEN (condition)]
Trigger_body
举例1:
  
CREATE OR REPLACE TRIGGER   restrict_age
BEFORE INSERT OR UPDATE OF age ON person
FOR EACH ROW
BEGIN
IF NOT (:NEW.per_id IN (’AD_PRES’, ’AD_VP’))
	AND :NEW.age > 25 THEN
       RAISE_APPLICATION_ERROR (-20202,’person can
	not in this amount’);
END IF;
END;
/ 

举例2:
 
 CREATE OR REPLACE TRIGGER audit_emp_values AFTER 
     DELETE OR INSERT OR UPDATE ON employees 
FOR EACH ROW
BEGIN
  INSERT INTO audit_emp_table (user_name, timestamp,
    id, old_last_name, new_last_name, old_title,
    new_title, old_salary, new_salary)
  VALUES (USER, SYSDATE, :OLD.employee_id,
    :OLD.last_name, :NEW.last_name, :OLD.job_id,
     :NEW.job_id, :OLD.salary, :NEW.salary );
END;
/ 
OLD 和 NEW 限定词只在行触发器中可用。在每一个 SQL 和 PL/SQL 语句中用冒号 (:) 前缀这些限定词。如果这些限定词在 WHEN 限制条件中被引用则无冒号 (:) 前缀。

举例3: