一、触发器

  触发器是当特定事件出现时自动执行的代码块。比如,每次对员工表进行增删改的操作时,向日志表中添加一条记录。触发器和存储过程是由区别的:触发器是根据某些条件自动执行的,存储过程是手动条用的。

  (一)触发器的类型:

    1、行级触发器:操作数据行的时候触发。

    2、语句级触发器:一个DML语句出发一次的触发器。行级触发器和语句级触发器一起也成为DML触发器。

    3、INSTEADOF 触发器:主要是在视图上定义的触发器。

    4、模式触发器:用户事务触发器。

    5、数据库触发器:创建在数据库事件上的触发器。

  (二)触发器可以分为三个部分:

    1、触发器语句:触发器语句是哪些可以导致触发器的事件,即在表或者视图上执行INSERT、DELETE、UPDATE之类的DML语句,在模式对象上执行的DDL语句或数据库事件。所有可以导致触发器的事件都是触发器的语句。

    2、触发器限制:触发器限制条件包含一个布尔表达式,该值必须为”真“才能激活触发器,如果该值为”假“或”未知“,将不运行触发器操作。

    3、触发器操作:触发器操作时触发器的主体,包含一些SQL语句和代码,这些代码在执行触发器有且触发器限制条件为”真“时运行。行级触发器允许触发器操作中的语句访问行的列值。

  

  (三)触发器的常用功能如下:

  1、允许/限制对表的修改。

  2、自动生成派生列。

  3、强制数据一致性。

  4、强制复杂的完整性约束条件。

  5、提供审计和日志记录。

  6、防止无效的事件处理。

  7、启动复杂的业务逻辑。

  由于触发器是对数据进行监控的一个对象,随时监控着数据库中的数据和表,造成使用触发器的性能低下。这点尤为重要。

二、创建触发器:

  语法:

  CREATE [OR REPLACE] TRIGGER trigger_name

  {BEFORE | AFTER | INSTEAD OF}

  {INSERT | DELETE | UDPATE | [OF column[,column]]}

  [OR {INSERT | DELETE | UPDATE [OF column[,column]]}]

  ON [schema.]table_or_view_name

  [REFERENCING [NEW AS new_row_name] [OLD AS old_row_name]]

  [FOR EACH ROW]

  [WHEN (condition)]

  [DECLARE

    variable_declation]

  BEGIN

    statements;

  [EXCEPTION

    exception_handlers]

  END[trigger_name];

  说明:

  trigger_name:触发器的名称

  BEFORE | AFTER :表示在事件发生之前或之后激活触发器

   INSTEAD OF:表示可以执行触发器代码来代替导致触发器调用的事件。

  INSERT | DELETE | UDPATE :指定构成触发器事件的数据库操作类型,UPDATE还可以指定列的列表。

  REFERENCING :指定新行(即将更新)和旧行(更新前)的其他名称,默认为NEW和OLD。

  table_or_view_name:触发器所监控的表或者视图的名称。

  FOR EACH ROW:表示是否对受影响的每一行都执行触发器,即行级触发器。如果不使用此语句,则为语句触发器,使用此语句则为行级触发器。

  WHEN (condition):限制执行触发器的条件,该条件可以包括新旧数据值的检查。

  DECLARE:声明触发器所使用的局部变量

  statements:触发器所执行的PL-SQL语句。

  exception_handlers:异常处理代码。

  例1:生成一个自动编号(行级触发器)

--创建测试表,学生表
CREATE TABLE student
(
stu_id NUMBER CONSTRAINT pk_id PRIMARY KEY,
stu_name VARCHAR2(20) NOT NULL,
stu_phone VARCHAR2(20) NOT NULL
);
--创建一个序列,从1开始累加,每次加1
CREATE SEQUENCE seq_student
START WITH 1 --序列开始,从1开始计数
INCREMENT BY 1 --每次增加1
NOMAXVALUE --不设置最大值
NOCYCLE --只累加,不循环
CACHE 20; --缓存20
create or replace trigger student_insert_seq
before insert on student --在插入之前
for each row --行级触发器
begin
:new.stu_id := seq_student.nextval; --将插入的stu_id属性设置为序列的下一个值
end student_insert_seq;
--插入数据
INSERT INTO student (stu_name,stu_phone) VALUES('张三','');
INSERT INTO student (stu_name,stu_phone) VALUES('李四',''); --查询,数据插入成功
SELECT * FROM student

  例2:实现表操作日志  

--新建日志表序列
CREATE SEQUENCE logs_id_squ INCREMENT BY 1
START WITH 1 MAXVALUE 9999999 NOCYCLE NOCACHE; --日志表
CREATE TABLE logs(
LOG_ID NUMBER(10) PRIMARY KEY,
LOG_TABLE VARCHAR2(10) NOT NULL,
LOG_DML VARCHAR2(10),
LOG_KEY_ID NUMBER(10),
LOG_DATE DATE,
LOG_USER VARCHAR2(15)
);
--创建日志触发器:表级触发器
create or replace trigger trig_log
after INSERT OR UPDATE OR DELETE
on emp
for each row
DECLARE
V_USERNAME VARCHAR2(20);
BEGIN
SELECT USER INTO V_USERNAME FROM dual; --获取当前用户
IF INSERTING THEN
INSERT INTO logs VALUES(logs_id_squ.nextval,'emp','insert',:new.Empno,sysdate,V_USERNAME);
ELSIF UPDATING THEN
INSERT INTO logs VALUES(logs_id_squ.nextval,'emp','update',:new.Empno,sysdate,V_USERNAME);
ELSIF DELETING THEN
INSERT INTO logs VALUES(logs_id_squ.nextval,'emp','delete',:new.Empno,sysdate,V_USERNAME);
END IF;
END TRIG_LOG;

三、触发器的注意事项

(1)、create trigger 语句的字符长度不能超多32kb;

(2)、触发器体内的select语句只能为select .....into .....结构,或者为定义游标所使用的select语句;

(3)、触发器中不能使用数据库事务控制语句,如:commit、rollback、savepoint语句;

(4)、由触发器调用的过程或函数也不能使用数据库事务控制语句;

(5)、触发器中不能使用lang、lang row类型;

(6)、触发器可以参照lob类型类的列值,但不能通过:new 来修改lob列中的值;

(6)、触发器所涉及的表收到表约束的限制

Oracle基础 触发器的更多相关文章

  1. Oracle基础<5>--触发器

    一.触发器 触发器是当特定事件出现时自动执行的代码块.比如,每次对员工表进行增删改的操作时,向日志表中添加一条记录.触发器和存储过程是由区别的:触发器是根据某些条件自动执行的,存储过程是手动条用的. ...

  2. 蜗牛—ORACLE基础之触发器学习(三)

    版权声明:本文为大腰子原创文章,如若转载,请标明原地址. https://blog.csdn.net/u010071361/article/details/30037215 建立一个触发器, 当职工表 ...

  3. Oracle基础学习笔记

    Oracle基础学习笔记 最近找到一份实习工作,有点头疼的是,有阶段性考核,这...,实际想想看,大学期间只学过数据库原理,并没有针对某一数据库管理系统而系统的学习,这正好是一个机会,于是乎用了三天时 ...

  4. ORACLE| ORACLE基础语法汇总

    创 ORACLE| ORACLE基础语法汇总 2018-07-18 16:47:34 YvesHe 阅读数 9141更多 分类专栏: [数据库]   版权声明:本文为博主原创文章,遵循CC 4.0 B ...

  5. oracle基础教程(8)oracle修改字符集

    oracle基础教程(8)oracle修改字符集 1.用dba连接数据库 -->sqlplus / as sysdba 2.查看字符集 -->SELECT parameter, value ...

  6. 图说Oracle基础知识(一)

    本文主要对Oralce数据库操作的基础知识进行一下梳理,以便进行归纳总结.适用于未使用过Oracle数据库的读者,或需要学习Oracle数据库方面的基础知识.如有不足之处,还请指正. 关于SQL介绍的 ...

  7. Oracle 基础学习笔记

    知识点 一.登陆数据库: 登陆数据库: sqlplus system/oracle123456 二.新建用户.授权(连接数据库.创建表.表空间.查询某用户下的表) 语法: create user [用 ...

  8. oracle基础教程oracle客户端详解

    oracle基础教程oracle客户端工具详解 参考网址:http://www.oraclejsq.com/article/010100114.html 该教程介绍了oracle自带客户端sqlplu ...

  9. Oracle基础 表分区

    Oracle基础 表分区 一.表分区 (一)表分区的分类 1.范围分区(range) 2.散列分区(hash) 3.列表分区(list) 4.复合分区:范围-哈希(range-hash).范围-列表( ...

  10. Oracle基础了解

    数据库: 关系型数据库 select * from 表名 非关系型数据库(做不到复杂查询) 以对象的形式进行存储 {"aaa":"ccc"}---键值对 ora ...

随机推荐

  1. HDU 1171Big Event in HDU(转01背包)

    题意: 给你一组数,分成差距最小的两份A,B(A>=B) 分析: 转01背包 注意: 01背包用一维数组 不要用二维 二维数组若是开太大,内存超限,开太小,RE #include "c ...

  2. UVA 10910 Marks Distribution

    题意 把数字T分成N个数的和,保证这N个数中最小的数大于P.求方案数目 另f[i][j]表示把i分成j个数的和的方案数 f[i][j]=f[i][j-1]+f[i-1][j-1]+f[i-2][j-1 ...

  3. usb驱动---What is the difference between /dev/ttyUSB and /dev/ttyACM【转】

    转自:http://blog.csdn.net/ppp2006/article/details/25654733 https://www.rfc1149.net/blog/2013/03/05/wha ...

  4. Fastjson.tojsonString中$ref对象重复引用问题

    import java.util.ArrayList; import java.util.List; import com.alibaba.fastjson.JSON; import com.alib ...

  5. 负载均衡技术之-lvs

    LVS简介 Internet的快速增长使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲, CPU.I/O处理能力很快会成为瓶颈.由于单台服 ...

  6. react 使用antd的TreeSelect树选择组件实现多个树选择循环

    需求说明,一个帐号角色可以设置管理多个项目的菜单权限 且菜单接口每次只能查询特定项目的菜单数据[无法查全部] 开发思路: 1,获取项目接口数组,得到项目数据 2,循环项目数据,以此为参数递归查询菜单数 ...

  7. spoj - Distinct Substrings(后缀数组)

    Distinct Substrings 题意 求一个字符串有多少个不同的子串. 分析 又一次体现了后缀数组的强大. 因为对于任意子串,一定是这个字符串的某个后缀的前缀. 我们直接去遍历排好序后的后缀字 ...

  8. 洛谷——P1348 Couple number

    P1348 Couple number 题目描述 任何一个整数N都能表示成另外两个整数a和b的平方差吗?如果能,那么这个数N就叫做Couple number.你的工作就是判断一个数N是不是Couple ...

  9. UVA——442 Matrix Chain Multiplication

    442 Matrix Chain MultiplicationSuppose you have to evaluate an expression like A*B*C*D*E where A,B,C ...

  10. Android开发实践:Java层与Jni层的数组传递

    转载:http://www.linuxidc.com/Linux/2014-03/97561.htm Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是 ...