触发器trigger是数据库提供给程序员和数据分析员来保证数据完整性的一种方法,
它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发。
比如当对一个表进行操作(insert,delete,update)时就会激活它执行。
触发器经常用于加强数据的完整性约束和业务规则等。

ORACLE触发器有三种类型,分别是:DML触发器、替代触发器和系统触发器。

DML触发器

DML触发器是由DML语句触发的。
例如数据库的INSERT、UPDATE、DELETE操作都可以触发该类型的触发器。
它们可以在这些语句之前或之后触发,或者在行级上触发(就是说对于每个受影响的行都触发一次)。

替代触发器

替代触发器只能使用在视图上,与DML不同的是,
DML触发器是运行在DML之外的,而替代触发器是代替激发它的DML语句运行。
替代触发器是行触发器。

系统触发器

这种触发器是发生在如数据库启动或关闭等系统事件时,不是在执行DML语句时发生,当然也可以在DDL时触发。

触发器功能强大,轻松可靠地实现许多复杂的功能,但是我们也应该慎用。为什么又要慎用呢?
触发器本身没有过错,但如果我们滥用,会造成数据库及应用程序的维护困难。
在数据库操作中,我们可以通过关系、触发器、存储过程、应用程序等来实现数据操作,
同时约束、缺省值也是保证数据完整性的重要保障。
如果我们对触发器过分的依赖,势必影响数据库的结构,同时增加了维护的复杂程度。

触发器组成

触发器主要由以下几个要素组成:
触发事件:引起触发器被触发的事件。
触发时间:触发器是在触发事件发生之前(BEFORE)还是之后(AFTER)触发,也就是触发事件和该触发器的操作顺序。
触发操作:触发器被触发之后的目的和意图,是触发器本身要做的事情。
触发对象:包括表、视图、模式、数据库。只有在这些对象上发生了符合触发条件的触发事件,才会执行触发操作。
触发条件:由WHEN子句指定一个逻辑表达式。
          只有当该表达式的值为TRUE时,遇到触发事件才会自动执行触发器,使其执行触发操作。
触发频率:说明触发器内定义的动作被执行的频率。即语句级(STATEMENT)触发器和行级(ROW)触发器:
语句级(STATEMENT)触发器:是指当某触发事件发生时,该触发器只执行一次;
行级(ROW)触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次。

语法:略

说明:
BEFORE和AFTER指出触发器的触发时间分别为前触发和后触发方式,
前触发是在执行触发事件之前触发当前所创建的触发器,后触发是在执行触发事件之后触发当前所创建的触发器。

REFERENCING子句说明相关名称,
在行触发器的PL/SQL块和WHEN子句中可以使用相关名称参照当前的新、旧列值,默认的相关名称为OLD和NEW。
触发器的PL/SQL块中应用相关名称时,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。

NEW只在UPDATE、INSERT的DML触发器内可用,它包含了修改发生后被影响行的值。
OLD只在UPDATE、DELETE的DML触发器内可用,它包含了修改发生前被影响行的值。

FOR EACH ROW选项说明触发器为行触发器。
行触发器和语句触发器的区别表现在:行触发器要求当一个DML语句操走影响数据库中的多行数据时,
对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;
而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。
当省略FOR EACH ROW 选项时,BEFORE和AFTER触发器为语句触发器,而INSTEAD OF触发器则只能为行触发器。

WHEN子句说明触发约束条件。
Condition为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用PL/SQL函数。
WHEN子句指定的触发约束条件只能用在BEFORE和AFTER行触发器中,不能用在INSTEAD OF行触发器和其它类型的触发器中。

INSTEAD OF选项(创建替代触发器)使ORACLE激活触发器,而不执行触发事件。
只能对视图和对象视图建立INSTEAD OF触发器,而不能对表、模式和数据库建立INSTEAD OF触发器。

ddl_event:一个或多个DDL事件,事件间用OR分开。
database_event:一个或多个数据库事件,事件间用OR分开。

示例1,在插入数据时,自动使用序列编号:

1 CREATE OR REPLACE TRIGGER EMP_INSERT_ID
2 BEFORE INSERT ON employee FOR EACH ROW
3 BEGIN
4    SELECT SEQ_ID.NEXTVAL INTO :NEW.ID FROM DUAL;
5 END;

1 示例2,在多表联接的视图中插入数据:
 2
 3 -- 创建视图
 4 CREATE OR REPLACE VIEW vw_emp AS
 5 SELECT e.name ename, e.address, d.name dname
 6 FROM employee e, dept d
 7 WHERE e.did = d.id;
 8
 9 -- 创建触发器
10 CREATE TRIGGER emp_insert_trigger
11    INSTEAD OF INSERT ON vw_emp
12 DECLARE
13    v_did dept.id%TYPE;
14 BEGIN
15    SELECT id INTO v_did FROM dept WHERE name = :NEW.dname;
16    INSERT INTO emp (name, address, did) VALUES (:NEW.ename, :NEW.address, v_did);
17 END emp_insert_trigger;

1 示例3,创建实例启动触发器:
 2
 3 -- 创建记录操作事件的表
 4 CREATE TABLE event_table(
 5    event VARCHAR2(50),
 6    time DATE
 7 );
 8
 9 -- 创建触发器
10 CREATE OR REPLACE TRIGGER tr_startup
11    AFTER STARTUP
12    ON DATABASE
13 BEGIN
14    INSERT INTO event_table(event, time)
15     VALUES(ora_sysevent, SYSDATE);
16 END;

DML触发器

DML触发器对我们开发人员来说是最常用的。
DML触发器是由数据库的INSERT、UPDATE、DELETE操作触发,
该类触发器可以在上述语句之前或之后执行,也可以每个受影响的行执行一次。

条件谓词:当在触发器中包含多个触发事件(INSERT、UPDATE、DELETE)的组合时,
为了分别针对不同的事件进行不同的处理,需要使用ORACLE提供的条件谓词:

INSERTING:当触发事件是INSERT时,取值为TRUE,否则为FALSE。
    UPDATING [(column_1,column_2,…,column_x)]:当触发事件是UPDATE时,如果修改了column_x列,则取值为TRUE,否则为FALSE。
    DELETING:当触发事件是DELETE时,则取值为TRUE,否则为FALSE。

示例:

1 CREATE OR REPLACE TRIGGER emp_sal_trigger
 2    BEFORE UPDATE OF salary OR DELETE
 3    ON employee FOR EACH ROW
 4    WHEN (old.did = 1)
 5 BEGIN
 6   CASE
 7      WHEN UPDATING ('salary') THEN
 8         IF :NEW.salary < :old.salary THEN
 9            RAISE_APPLICATION_ERROR(-20001, '部门1的员工工资不能降');
10         END IF;
11      WHEN DELETING THEN
12           RAISE_APPLICATION_ERROR(-20002, '不能删除部门1的员工记录');
13   END CASE;
14 END emp_sal_trigger;

5. 替代触发器

INSTEAD OF用于对视图的DML触发,由于视图有可能是由多个表联结(JOIN)而成,因而并非所有的视图都是可更新的,但可以按照所需的方式执行更新。

创建INSTEAD OF触发器需要注意以下几点:

只能被创建在视图上,并且该视图没有指定WITH CHECK OPTION选项。
不能指定BEFORE或AFTER选项。
FOR EACH ROW子句是可选的。
没有必要在针对一个表的视图上创建INSTEAD OF触发器,只要创建DML触发器就可以了。

示例:

1 CREATE OR REPLACE TRIGGER emp_delete_trigger
2    INSTEAD OF DELETE ON vw_emp FOR EACH ROW
3 DECLARE
4    v_did dept.id%TYPE;
5 BEGIN
6    SELEC id INTO v_did FROM dept WHERE name=:OLD.dname;
7    DELETE FROM employee WHERE did= v_did;
8 END emp_delete_trigger;

6. 系统触发器

系统触发器可以在DDL或数据库系统上被触发
,数据库系统事件包括数据库服务器的启动或关闭,用户的登录与退出、数据库服务错误等。

系统事件触发器既可以建立在一个模式上,又可以建立在整个数据库上。
当建立在模式(SCHEMA)之上时,只有模式所指定用户的DDL操作和它们所导致的错误才激活触发器,默认时为当前用户模式。
当建立在数据库(DATABASE)之上时,该数据库所有用户的DDL操作和他们所导致的错误,以及数据库的启动和关闭均可激活触发器。

系统触发器的种类和事件出现的时机:

1 -- 创建记录用户登录注销日志的表
 2 CREATE TABLE log_on_off_log
 3 (user_name VARCHAR2(20),
 4  logon_date timestamp,
 5  logoff_date timestamp);
 6
 7 -- 创建登录触发器
 8 CREATE OR REPLACE TRIGGER logon_trigger
 9    AFTER LOGON ON DATABASE
10 BEGIN
11    INSERT INTO log_on_off_log (user_name, logon_date) VALUES (ora_login_user, systimestamp);
12 END logon_trigger;
13
14 -- 创建退出触发器
15 CREATE OR REPLACE TRIGGER logoff_trigger
16    BEFORE LOGOFF ON DATABASE
17 BEGIN
18    INSERT INTO log_on_off_log (user_name, logoff_date) VALUES (ora_login_user, systimestamp);
19 END logoff_trigger;

事件                        触发时机              说明
STARTUP                     AFTER                   启动数据库实例之后触发
SHUTDOWN                     BEFORE                   关闭数据库实例之前触发
SERVERERROR                 AFTER                   数据库服务器发生错误之后触发
LOGON                         AFTER                   成功登录到数据库后触发
LOGOFF                         BEFORE                   断开数据库连接之前触发
DDL                         BEFORE,AFTER           在执行大多数DDL语句之前、之后触发
CREATE / ALTER / DROP         BEFORE,AFTER           在执行CREATE或ALTER或DROP语句创建数据库对象之前、之后触发
RENAME                      BEFORE,AFTER           执行RENAME语句更改数据库对象名称之前、之后触发
GRANT / REVOKE                 BEFORE,AFTER           执行GRANT语句授予权限或REVOKE撤销权限之前、之后触发
AUDIT / NOAUDIT             BEFORE,AFTER           执行AUDIT或NOAUDIT进行审计或停止审计之前、之后触发

备注:随笔中内容来源于网上资料整理,仅供参考。

Oracle数据库之触发器(一)的更多相关文章

  1. oracle数据库之触发器

    触发器是许多关系数据库系统都提供的一项技术.在 ORACLE 系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的 PL/SQL 块. 一. 触发器类型 触发器在数据库里以独立的对象存储,它与 ...

  2. Oracle数据库之触发器(二)

    DML触发器是指在进行insert.update或delete操作时触发的程序体.如果你想在用户对数据进行操作时,记录或限制其操作,就可以用DML触发器.举例来说,我想统计我的网站用户的注册.注销或者 ...

  3. [转帖] Oracle数据库 通过触发器 限制登录ip

    转帖 From https://yq.aliyun.com/ziliao/123360 create or replace trigger logon_ip_control after logon o ...

  4. Oracle数据库——触发器的创建与应用

    一.涉及内容 1.理解触发器的概念.作用和类型. 2.练习触发器的创建和使用. 二.具体操作 (实验) 1.利用触发器对在scott.emp表上执行的DML操作进行安全性检查,只有scott用户登录数 ...

  5. oracle数据库高级应用之《触发器的建立》

    (一)oracle数据库触发器的建立 eg1 CREATE OR REPLACE TRIGGER TRIGGER_ON_TD_DEPARTMENT AFTER INSERT OR UPDATE OR ...

  6. Oracle数据库之PL/SQL触发器

    Oracle数据库之PL/SQL触发器 1. 介绍 触发器(trigger)是数据库提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是 ...

  7. oracle数据库触发器(trigger)用法总结

    from:http://blog.csdn.net/zhanzhib/article/details/48729417 触发器的意思就是当我们对数据库对象(一般是表或视图)进行insert.updat ...

  8. Oracle数据库触发器使用(删除触发)

    当我们需要用到触发器的时候,还是很方便,你会指定当我在操作某一事件时触发效果完成我所希望完成的事情:这就是触发器, 下面我给大家上一串代码,这是一个当我在操作删除事件操作时候,我希望把即将删除那条数据 ...

  9. Oracle数据库 常用的触发器命令

    创建自增序列,创建触发器(在触发时间中操纵序列,实现主键自增): Oracle数据库不支持自增方法 create sequence seq_userInfo_usid start with ;--创建 ...

随机推荐

  1. MSSQL sql常用判断语句

    .判断数据库是否存在 if exists (select * from sys.databases where name = '数据库名')    drop database [数据库名]  2 判断 ...

  2. redis为什么内存不宜过大

    redis的高性能.稳定性都是不用怀疑的,但如果redis塞入数据过多,内存过大,那如果出问题,那它可能会给我们的就是灾难性的. 1 主库宕机 主库宕机,常见的策略为“切主”.具体为从该集群剩余从库中 ...

  3. Vue过渡:用Velocity实现JavaScript钩子

    Velocity is an animation engine with a similar API to jQuery's $.animate(). It has no dependencies, ...

  4. crontab自动执行任务,失败原因记录

    服务器上使用crontab部署这两个每分钟自动执行的命令.首先,这两个命令是之前的人部署的,在我接手之前,就一直在了的.根据命令,实际上应该是做到每分钟都执行一次脚本.但是实际操作中,却发现,其实并没 ...

  5. 图解Http阅读笔记(一)

    1.网络基础 TCP/IP 1.1TCP /IP 协议族   计算机与网络设备要相互通信,双方就必须基于相同的方法.比如,如何探测到通信目标.由哪一边先发起通信.使用哪种语言进行通信.怎样结束通信等规 ...

  6. JSP基础--javaBean

    JavaBean 1 JavaBean概述 1.1 什么是JavaBean JavaBean是一种规范,也就是对类的要求.它要求Java类的成员变量提供getter/setter方法,这样的成员变量被 ...

  7. Python入门习题1.温度转换

    这一节的课堂例题为: 例1.编写一个Python程序,完成摄氏度到华氏度,华氏度到摄氏度的温度转换. 解: (1)分析问题:利用程序实现温度转换,由用户输入温度值,程序给出输出结果. (2)划分边界: ...

  8. hdu6311 Cover (欧拉路径输出)

    hdu6311Cover 题目传送门 题意:有最少用多少条边不重复的路径可以覆盖一个张无向图. 分析:对于一个连通块(单个点除外),如果奇度数点个数为 k,那么至少需要max{k/2,1}  条路径. ...

  9. hdu4734 F(x)(数位dp)

    题目传送门 F(x) Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  10. C#设计模式:装饰者模式(Decorator Pattern)

    一,装饰者模式(Decorator Pattern):装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. 二,在以上代码中我们是中国人是根本行为,我们给中国人装饰我会说英语 ...