Oracle基础知识(五) - 触发器的分类:DML触发器

参考网址:http://hi.baidu.com/bystander1983/item/f065c00cbe25508d03ce1b3b,原文稍微乱一些,感谢原作者的分享。


1. 触发器的分类

  • DML触发器

  • DDL触发器

  • 系统触发器

  • 替代触发器

2. 触发器的执行顺序

1. 如果存在语句级BEFORE触发器,则先执行一次语句级BEFORE触发器。

2. 在SQL语句的执行过程中,如果存在行级BEFORE触发器,则SQL语句在对每一行操作之前,都要先执行一次行级BEFORE触发器,然后才对行进行操作。

如果存在行级AFTER触发器,则SQL语句在对每一行操作之后,都要再执行一次行级AFTER触发器。 

3. 如果存在语句级AFTER触发器,则在SQL语句执行完毕后,要最后执行一次语句级AFTER触发器。


3. 行级触发器与表级触发器(语句触发器)

行级触发器对DML语句影响的每个行执行一次;

语句级触发器对每个DML语句执行一次,如果在TABLE表中插入的数据为500行,那么这个表上的语句级触发器只执行一次,而行级的触发器就要执行500次了。 

若在触发器定义中出现FOR EACH ROW子句,则为行级触发器,否则为表级触发器(语句触发器).

4. DML触发器

DML触发器是定义在表上的触发器,有DML事件引发。

4.1 DML事件(3种)

INSERT 在表或视图中插入数据时触发

UPDATE 修改表或视图中的数据时触发

DELETE 在删除表或视图中的数据时触发

4.2 编写DML触发器的要素

  • 确定触发的表,即在其上定义触发器的表

  • 确定触发的事件,DML触发器的触发事件有INSERT、UPDATE和DELETE三种

  • 确定触发时间。触发的时间有BEFORE和AFTER两种,分别表示触发动作发生在DML语句执行之前和语句执行之后

  • 确定触发级别,有语句级触发器和行级触发器两种。语句级触发器表示SQL语句只触发一次触发器,行级触发器表示SQL语句影响的每一行都要触发一次

4.3 相关问题备注

1. 如果有多个触发器被定义成为相同时间、相同事件触发,且最后定义的触发器是有效的,则最后定义的触发器被触发,其他触发器不执行。 

2. 一个触发器可由多个不同的DML操作触发。在触发器中,可用INSERTING、DELETING、UPDATING谓词来区别不同的DML操作。

     这些谓词可以在IF分支条件语句中作为判断条件来使用。 

3. 在行级触发器中,用:new 和:old(称为伪记录)来访问数据变更前后的值。

    但要注意,INSERT语句插入一条新记录,所以没有:old记录,而DELETE语句删除掉一条已经存在的记录,所以没有:new记录。

     UPDATE语句既有:old记录,也有:new记录,分别代表修改前后的记录。

    引用具体的某一列的值的方法是: :old.字段名或:new.字段名。

    触发器体内禁止使用COMMIT、ROLLBACK、SAVEPOINT语句,也禁止直接或间接地调用含有上述语句的存储过程。 

4.4 创建触发器

CREATE [OR REPLACE] TRIGGER 触发器名
{BEFORE|AFTER|INSTEAD OF} 触发事件1 [OR 触发事件2...]
ON 表名
WHEN 触发条件
[FOR EACH ROW]
DECLARE
声明部分
BEGIN
主体部分
END; 

其中:

OR REPLACE:表示如果存在同名触发器,则覆盖原有同名触发器。

BEFORE、AFTER和INSTEAD OF:说明触发器的类型。

WHEN 触发条件:表示当该条件满足时,触发器才能执行。

触发事件:指INSERT、DELETE或UPDATE事件,事件可以并行出现,中间用OR连接。

对于UPDATE事件,还可以用以下形式表示对某些列的修改会引起触发器的动作:

UPDATE OF 列名1,列名2...

ON 表名:表示为哪一个表创建触发器。

FOR EACH ROW:表示触发器为行级触发器,省略则为语句级触发器。


示例:

表:

很简单,只有一个ID,一个NAME

create table T_YGY_DEMO_BOOK2
(
  ID   NUMBER(11) not null,
  NAME VARCHAR2(100) not null
)

Oracle基础知识(五) - 触发器的分类:DML触发器_第1张图片


1. 对表T_YGY_DEMO_BOOK2进行INSERT,UPDATE,DELETE操作时,输出相应的记录。

CREATE OR REPLACE TRIGGER TRI_YGY_BOOK2_LOG

BEFORE INSERT OR UPDATE OR DELETE

ON T_YGY_DEMO_BOOK2

BEGIN

   IF INSERTING THEN DBMS_OUTPUT.put_line('触发器日志:要添加一条记录');
 

   ELSIF UPDATING THEN DBMS_OUTPUT.put_line('触发器日志:要修改一条记录');
  

   ELSIF DELETING THEN DBMS_OUTPUT.put_line('触发器日志:要删除一条记录');
   
   END IF;

END;


/

2. 对表T_YGY_DEMO_BOOK2进行更新操作时,判断ID是否大于5000,并输出不同的记录

CREATE OR REPLACE TRIGGER TRI_YGY_BOOK2_VALUE

BEFORE UPDATE

ON T_YGY_DEMO_BOOK2

FOR EACH ROW

BEGIN

   IF :OLD.ID>5000 THEN DBMS_OUTPUT.put_line('触发器日志:要更新的id大于5000.');
   
   ELSE DBMS_OUTPUT.put_line('触发器日志:要更新的id小于5000');
   
   END IF;

END;

/


你可能感兴趣的:(oracle,触发器,分类)