在ORACLE系统里,触发器类似函数和过程。
1、触发器类型:(一般为:语句级触发器和行级触发器。)
1)、DML触发器: 创建在表上,由DML事件引发
2)、instead of触发器: 创建在视图上并且只能在行级上触发,用于替代insert,delete等操作(由于oracle中不能直接对有两个以上的表建立的视图进行DML操作,所以给出替代触发器,它是专门为进行视图操作的一种处理方法)
3)、DDL触发器: 触发事件时数据库对象的创建和修改
4)、数据库事件触发器:定义在数据库或者模式上,由数据库事件触发

语法:
create or replace trigger 触发器名
<before | after | instead of> <insert | update | delete>--<insert | update | delete>可以选择一个或多个DML语句,如果选择多个,则用or分开,如:insert or update。
on 表名或者视图名或者用户名或者数据库名
[for each row] [触发级别]针对一个表或视图创建trigger时分为statement级别与row级别的trigger.所谓statement级别是说一个sql语句触发一次trigger,而如果是row级别则一个sql语句涉及到多行数据则trigger会被触发多次
when(condition)[when判断条件]
[declare 变量] 11g
begin
pl/sql语句;
end 触发器名;
(注:代码涉及到对关联表的数据操作,在行级触发器中使用,将会报ORA-04091错误。这时可以通过自制事务来规避,弊端是使用自制事务后无法回滚rollback)
触发时间:before/after 在指定的事件发生之前/后执行触发器 instead of 触发器用在对视图的更新上。
触发事件:Insert,update,delete,create(创建对象时),alter,drop,logon/logoff(用户的登录或注销时执行触发器),startup/shutdown(数据库打开或关闭时执行触发器)。
常见的是DML(insert,update,delete) , DDL(create,alter,drop)语句
触发级别:for each row(行级触发)对触发事件影响的每一行执行触发器,即触发机制是基于行的。改一行数据,触发一次。
不写为语句触发(对触发事件只能触发一次,而且不能该问受触发器影响的每一行的值。既无论这条SQL语句影响多少条记录,触发器都只触发一次。)
WHEN后跟的condition:是触发器的响应条件,只对BEFORE和AFTER行级触发器有效,当操作的记录满足condition时,触发器才被执行,否则不执行。Condition中可以通过new对象和old对象不带“:”(注意区别于前面的:new和:old,在代码中引用需要加上冒号)来引用操作的记录。

2、简例
创建测试用表:
create table emp_bak1 as select * from emp;
create table emp_bak2 as select * from emp;

例1:

create or replace trigger insert_emp
after insert on emp_bak1
for each row
declare --Declare后面跟的是本地变量定义部分,如果没有本地变量定义,此部分可以去掉
test_val emp_bak1.ename%type;--根据表的字段定义变量类型
begin
dbms_output.put_line('员工编号:'||:new.empno);
dbms_output.put_line('员工姓名:'||:new.ename);
dbms_output.put_line('职位:'||:new.job);
dbms_output.put_line('工资:'||:new.sal);
dbms_output.put_line('所在部门:'||:new.deptno);
dbms_output.put_line('---触发器已被执行---');
--select ename into test_val from emp_bak1 where empno = 7839;--ORA-04091
select :new.empno into test_val from dual;
dbms_output.put_line('---测试--->'||test_val);
end; insert into emp_bak1 (empno, ename, job, sal, deptno) values ('', 'SM', 'IT', '', '');

oracle默认的 用old代表老数据 new代表新数据(这两个变量只有在使用了关键字 "FOR EACH ROW"时才存在;referencing new as new_val old as old_val:这个可以更改新旧值的名字来引用新值,旧值)
insert时 只有new 没有old
delete时 只有old 没有new
update时 二者都可用

create or replace trigger delete_emp
before delete on emp_bak1 --删除操作前触发
for each row
begin
insert into emp_bak2
(empno, ename, job, sal, deptno)
values
(:old.empno, :old.ename, :old.job, :old.sal, :old.deptno);
dbms_output.put_line('-----有数据删除,员工号为'||:old.empno||'详细信息见emp_bak2表------');
end delete_emp; insert into emp_bak1 (empno, ename, job, sal, deptno) values ('', 'K', 'TE', '', '');
delete from emp_bak1 where empno = 777;

例2:指定条件列触发

create or replace trigger tri_01
after insert or update of sal on emp_bak1
for each row
begin
if inserting then
dbms_output.put_line('新人入驻有收入sal');
elsif updating then
dbms_output.put_line('sal有变动');
end if;
end tri_01; update emp_bak1 set sal = 888 where empno = 7934;--触发
update emp_bak1 set comm = 666 where empno = 7934;--未触发

注:第二行中的of sal on emp_bak1 是在表emp_bak1的sal字段发生变更时才触发操作,
在触发器主体的if语句表达式中,inserting, updating和deleting可以用来区分当前是在做哪一种DML操作,可以作为把多个类似触发器合并在一个触发器中判别触发事件的属性。

例3:when条件限制

create or replace trigger tri_02
before update of sal, comm or delete on emp_bak1
for each row
when (old.deptno = 30) --注:old前不带':'且结尾不带';'
begin
case
when updating('sal') then
dbms_output.put_line('原来薪资:'||:old.sal||';变更后薪资:'||:new.sal||';');
if :new.sal < :old.sal then
dbms_output.put_line('降薪不被允许');
raise_application_error(-20001, '部门30的人员的工资不能降');
end if;
when updating('comm') then
dbms_output.put_line('原来奖金:'||:old.comm||';变更后奖金:'||:new.comm||';');
if :new.comm < :old.comm then
dbms_output.put_line('降奖金不被允许');
raise_application_error(-20002, '部门30的人员的奖金不能降');
end if;
when deleting then
raise_application_error(-20003, '部门30的人员不能删');
end case;
end;

select * from emp_bak1 where deptno = 30;
update emp_bak1 set comm = 2000 where empno = 7499;
update emp_bak1 set sal = 20000 where empno = 7698;

raise_application_error相当于拒绝了插入或者修改事务
oracle允许自定义的错误代码的范围为-20000-->20999
raise_application_error(-20001,'ErrorCode');

例4:instead of触发器
instead of 选项使ORACLE激活触发器,而不执行触发事件。只能对视图和对象视图建立instead of触发器,而不能对表、模式和数据库建立instead of 触发器。

--语法类似:
create [or replace] trigger trigger_name
instead of
{insert | delete | update [of column [, column …]]}
on view_name --只能定义在视图上
[referencing {old [as] old_val | new [as] new_val| parent as parent}]--可以给old/new对象赋予新的名称(可以不要)
[for each row ] --因为instead of触发器只能在行级上触发,所以没有必要指定
[when condition]
pl/sql_block | call procedure_name;

视图创建

create view view_emp as
select deptno,count(*) count_no,sum(sal) sal from emp group by deptno;

对基表处理过的视图,在删除时会报下面的错误
ORA-01732: 此视图的数据操纵操作非法
此时可以创建INSTEAD_OF触发器来为 DELETE 操作执行所需的处理,即删除EMP表中所有基准行

create or replace trigger view_tri_03
instead of delete on view_emp
for each row
begin
delete from emp where deptno= :old.deptno;
dbms_output.put_line('从emp基表中删除部门编号为:'||:old.deptno||'的基础人员数据。');
end view_tri_03;

可看出此触发器只是触发了一个删除部门号的事件,实际更改的还是基表。

例5:语句级触发器

create or replace trigger tri_04
after insert or update of sal on emp_bak1
declare
v_sumsal number;
begin
select sum(sal) into v_sumsal from emp_bak1;
if v_sumsal > 50000 then
raise_application_error(-20001, '总工资超过50000');
end if;
end;

--如果用行级触发器(for each row)会报ORA-04091错误

insert into emp_bak1 (empno, ename, job, sal, deptno) values ('777', 'K', 'TE', '90000', '30');

(注:此为学习记录笔记,仅供参考若有问题请指正,后续补充......)

参考资料:https://www.cnblogs.com/wishyouhappy/p/3665851.html

参考资料:https://blog.csdn.net/weiwenhp/article/details/9179891

参考资料:https://www.cnblogs.com/hyq0002013/p/6085981.html

参考资料:https://blog.csdn.net/IndexMan/article/details/8023740

 

Oracle触发器简单使用记录的更多相关文章

  1. Oracle触发器简单入门记录

    写在前面: 最近,老项目新增了日报优化的需求,丽姐让我用触发器去实现当数据插入或者更新的时候,实现对日报表数据更新操作.嗯嗯嗯呢,之前学习数据库的时候,有碰到过触发器,但都是一跳而过,也没怎么去真正的 ...

  2. 【oracle】触发器简单实现

    目标:实现实时备份uertest表数据至usertest_temp中,两表结构一致 解决:用oracle触发器实现同步 结果: 1.建表 -- 简单的用户表 create table USERTEST ...

  3. (转)oracle触发器使用:after insert 与before insert的简单使用注意

    本文转载自:http://blog.csdn.net/kuangfengbuyi/article/details/41446125 创建触发器时,触发器类型为after insert , 在begin ...

  4. oracle触发器加条件判断

    oracle触发器加条件判断,如果某个字段,isnode=0,那么不执行下面的方法,数据如下: create or replace trigger tr_basestation_insert_emp ...

  5. Oracle 触发器在日志管理开发中的应用

    摘要: 本文讨论了利用数据库中的触发器对日志管理进行设计与实现的方法, 是对原来在客户端软件中编写日志管理方法的一种改进, 并给出了 Oracle9i 中的实例演示.关键词: Oracle; 触发器; ...

  6. SQL server与Oracle触发器的创建与使用

    SQL Server 1创建触发器 GO BEGIN IF (object_id('WMY', 'tr') is not null) DROP trigger WMY END; GO CREATE T ...

  7. Oracle触发器用法实例详解

    转自:https://www.jb51.net/article/80804.htm. 本文实例讲述了Oracle触发器用法.分享给大家供大家参考,具体如下: 一.触发器简介 触发器的定义就是说某个条件 ...

  8. Oracle复习(有记录才能沉淀.......)

    一.Oracle准备工作 1.安装Oracle Oracle数据库产品是免费的,我们可以从Oracle的官方网站(http://www.oracle.com)下载到程序安装包,Oracle在Windo ...

  9. 问题:Oracle出发器;结果:1、Oracle触发器详解,2、Oracle触发器示例

    ORACLE触发器详解 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触发器触发次序 8.2.2 创 ...

随机推荐

  1. Sprig 面试中 问及 DI,IOC, AOP

    面向切面编程,把散落在程序中的公共部分提取出来,做成切面类,这样的好处在于,代码的可重用,一旦涉及到该功能的需求发生变化,只要修改该代码就行,否则,你要到处修改,如果只要修改1.2处那还可以接受,万一 ...

  2. 对ArrayList(Vector)的排序

    当需要对ArrayList(Vector)里面的元素进行简单的排序时,可以使用Collections.sort();这个方法 import java.util.ArrayList; import ja ...

  3. [LeetCode 题解]:Path Sum

    前言   [LeetCode 题解]系列传送门:  http://www.cnblogs.com/double-win/category/573499.html   1.题目描述 Given a bi ...

  4. [LeetCode 题解]: Insertion Sort List

    Sort a linked list using insertion sort. 题目要求:链表的插入排序,由于没有时间复杂度的要求,可以直接循环操作. /** * Definition for si ...

  5. [Erlang01] 使用catch与try catch避免嵌套nest_case

    catch 如此好用,为什么官方还是推荐用try catch? 1. catch 的用法非常简单: catch case do_check(Test) of {ok,Result} -> do_ ...

  6. T-SQL逻辑查询

    理解T-SQL的逻辑查询顺序是学习SQL Server的基础. T-SQL逻辑执行顺序 (8)    SELECT (9) DISTINCT (11) <TOP_specification> ...

  7. Transaction And Lock--事务中使用return会回滚事务吗?

    事务中使用return会回滚事务吗? 答案:不会,如果在事务中没有显示提交或回滚事务边return,事务不会被提交或回滚,在C#中,如果没有使用连接池,则事务在连接断开和销毁时被强制回滚,如果使用连接 ...

  8. ArrayList用法详解与源码分析

    说明 此文章分两部分,1.ArrayList用法.2.源码分析.先用法后分析是为了以后忘了查阅起来方便-- ArrayList 基本用法 1.创建ArrayList对象 //创建默认容量的数组列表(默 ...

  9. ZKEACMS 自定义表单的使用

    ZKEACMS Core 2.2 已经发布了,其中主要添加了自定义表单的功能.使用自定义表单的功能,您可以在几分钟内就创建一个表单,并用它来收集一些信息.导出收集的信息,就可以做一些统计分析. 创建表 ...

  10. Filter 设计模式编码实践

    原文地址: haifeiWu和他朋友们的博客 博客地址:www.hchstudio.cn 欢迎转载,转载请注明作者及出处,谢谢! 最近项目中遇到各种输出数据监控,数据校验等逻辑,一个个实现很是麻烦.项 ...