触发器 是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。

功能: 
1、 允许/限制对表的修改 
2、 自动生成派生列,比如自增字段 
3、 强制数据一致性 
4、 提供审计和日志记录 
5、 防止无效的事务处理 
6、 启用复杂的业务逻辑 
开始 
create trigger biufer_employees_department_id 
before insert or update 
of department_id 
on employees 
referencing old as old_value 
new as new_value 
for each row 
when (new_value.department_id<>80 ) 
begin 
:new_value.commission_pct :=0; 
end; 

触发器的组成部分: 
1、 触发器名称 
2、 触发语句 
3、 触发器限制 
4、 触发操作 
1、 触发器名称 
create trigger biufer_employees_department_id 
命名习惯: 
biufer(before insert update for each row) 
employees 表名 
department_id 列名 
2、 触发语句 
比如: 
表或视图上的DML语句 
DDL语句 
数据库关闭或启动,startup shutdown 等等 
before insert or update 
of department_id 
on employees 
referencing old as old_value 
new as new_value 
for each row 
说明: 
1、 无论是否规定了department_id ,对employees表进行insert的时候 
2、 对employees表的department_id列进行update的时候 
3、 触发器限制 
when (new_value.department_id<>80 ) 
限制不是必须的。此例表示如果列department_id不等于80的时候,触发器就会执行。 
其中的new_value是代表跟新之后的值。 
4、 触发操作 
是触发器的主体 
begin 
:new_value.commission_pct :=0; 
end; 
主体很简单,就是将更新后的commission_pct列置为0 
触发: 
insert into employees(employee_id, 
last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct ) 
values( 12345,'Chen','Donny', sysdate, 12, ‘donny@hotmail.com',60,10000,.25); 
select commission_pct from employees where employee_id=12345; 
触发器不会通知用户,便改变了用户的输入值。 
触发器类型: 
1、 语句触发器 
2、 行触发器 
3、 INSTEAD OF 触发器 
4、 系统条件触发器 
5、 用户事件触发器 
1、 语句触发器 
是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、 
DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次 
。比如,无论update多少行,也只会调用一次update语句触发器。 
例子: 
需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。 
Create table foo(a number); 
Create trigger biud_foo 
Before insert or update or delete 
On foo 
Begin 
If user not in (‘DONNY') then 
Raise_application_error(-20001, ‘You don't have access to modify this table.'); 
End if; 
End; 

即使SYS,SYSTEM用户也不能修改foo表 
[试验] 
对修改表的时间、人物进行日志记录。 
1、 建立试验表 
create table employees_copy as select *from hr.employees 
2、 建立日志表 
create table employees_log( 
who varchar2(30), 
when date); 
3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log 表。 
Create or replace trigger biud_employee_copy 
Before insert or update or delete 
On employees_copy 
Begin 
Insert into employees_log( 
Who,when) 
Values( user, sysdate); 
End; 

4、 测试 
update employees_copy set salary= salary*1.1; 
select *from employess_log; 
5、 确定是哪个语句起作用? 
即是INSERT/UPDATE/DELETE中的哪一个触发了触发器? 
可以在触发器中使用INSERTING / UPDATING / DELETING 条件谓词,作判断: 
begin 
if inserting then 
----- 
elsif updating then 
----- 
elsif deleting then 
------ 
end if; 
end; 
if updating(‘COL1') or updating(‘COL2') then 
------ 
end if; 
[试验] 
1、 修改日志表 
alter table employees_log 
add (action varchar2(20)); 
2、 修改触发器,以便记录语句类型。 
Create or replace trigger biud_employee_copy 
Before insert or update or delete 
On employees_copy 
Declare 
L_action employees_log.action%type; 
Begin 
if inserting then 
l_action:='Insert'; 
elsif updating then 
l_action:='Update'; 
elsif deleting then 
l_action:='Delete'; 
else 
raise_application_error(-20001,'You should never ever get this error.'); 
Insert into employees_log( 
Who,action,when) 
Values( user, l_action,sysdate); 
End; 

3、 测试 
insert into employees_copy( employee_id, last_name, email, hire_date, job_id) 
values(12345,'Chen','Donny@hotmail',sysdate,12); 
select *from employees_log 
update employees_copy set salary=50000 where employee_id = 12345; 
2、 行触发器 
是指为受到影响的各个行激活的触发器,定义与语句触发器类似,有以下两个例外: 
1、 定义语句中包含FOR EACH ROW子句 
2、 在BEFORE……FOR EACH ROW触发器中,用户可以引用受到影响的行值。 
比如: 
定义: 
create trigger biufer_employees_department_id 
before insert or update 
of department_id 
on employees_copy 
referencing old as old_value 
new as new_value 
for each row 
when (new_value.department_id<>80 ) 
begin 
:new_value.commission_pct :=0; 
end; 

Referencing 子句: 
执行DML语句之前的值的默认名称是 :old ,之后的值是 :new 
insert 操作只有:new 
delete 操作只有 :old 
update 操作两者都有 
referencing子句只是将new 和old重命名为new_value和old_value,目的是避免混淆。比如操作一个名为 
new的表时。 
作用不很大。 
[试验]:为主健生成自增序列号 
drop table foo; 
create table foo(id number, data varchar2(20)); 
create sequence foo_seq; 
create or replace trigger bifer_foo_id_pk 
before insert on foo 
for each row 
begin 
select foo_seq.nextval into :new.id from dual; 
end; 

insert into foo(data) values(‘donny'); 
insert into foo values(5,'Chen'); 
select * from foo; 
3、 INSTEAD OF 触发器更新视图 
Create or replace view company_phone_book as 
Select first_name||', '||last_name name, email, phone_number, 
employee_id emp_id 
From hr.employees; 
尝试更新email和name 
update hr.company_phone_book 
set name='Chen1, Donny1' 
where emp_id=100 
create or replace trigger update_name_company_phone_book 
INSTEAD OF 
Update on hr.company_phone_book 
Begin 
Update hr.employees 
Set employee_id=:new.emp_id, 
First_name=substr(:new.name, instr(:new.name,',')+2), 
last_name= substr(:new.name,1,instr(:new.name,',')-1), 
phone_number=:new.phone_number, 
email=:new.email 
where employee_id=:old.emp_id; 
end; 
4、 系统事件触发器 
系统事件:数据库启动、关闭,服务器错误 
create trigger ad_startup 
after startup 
on database 
begin 
-- do some stuff 
end; 

5、 用户事件触发器 
用户事件:用户登陆、注销,CREATE / ALTER / DROP / ANALYZE / AUDIT / GRANT / REVOKE / 
RENAME / TRUNCATE / LOGOFF 
例子:记录删除对象 
1. 日志表 
create table droped_objects( 
object_name varchar2(30), 
object_type varchar2(30), 
dropped_on date); 
2.触发器 
create or replace trigger log_drop_trigger 
before drop on donny.schema 
begin 
insert into droped_objects values( 
ora_dict_obj_name, -- 与触发器相关的函数 
ora_dict_obj_type, 
sysdate); 
end; 

3. 测试 
create table drop_me(a number); 
create view drop_me_view as select *from drop_me; 
drop view drop_me_view; 
drop table drop_me; 
select *from droped_objects 
禁用和启用触发器 
alter trigger <trigger_name> disable; 
alter trigger <trigger_name> enable; 
事务处理: 
在触发器中,不能使用commit / rollback 
因为ddl语句具有隐式的commit,所以也不允许使用 
视图: 
dba_triggers

转载于:https://blog.51cto.com/msuccess/1416449

oracle 触发器 学习笔记相关推荐

  1. oracle buffer block,8 Oracle深度学习笔记——BUFFER CACHE深入一

    8.Oracle深度学习笔记--BUFFER CACHE深入一 最近项目一直和ORACLE死磕,感觉总是找不到出口,只能多看书少说话了. 先记录多少是多少吧! BUFFER CACHE在ORACLE的 ...

  2. oracle数据库的model,Oracle 11g学习笔记–model子句

    Oracle 11g学习笔记–model子句 oracle 10g中新增的model子句可以用来进行行间计算.model子句允许像访问数组中元素那样访问记录中的某个列,这就提供了诸如电子表格计算之类的 ...

  3. Oracle 10g学习笔记(一)

    前言 很不好意思的坦白本人是刚刚学习oracle的菜鸟,以下内容是节取的书中一些值得注意的事项,因为只涉及oracle最初级的知识,并没有太深的内容,希望各位oralce高手们能够帮忙指点指点. Or ...

  4. 【Oracle Hint】Oracle Hint学习笔记【一】

    一.Oracle Hint的一些基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer). 它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划. Oracl ...

  5. 2 Oracle深度学习笔记 内存架构之UGA

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 2.Or ...

  6. 2.Oracle深度学习笔记——内存架构之UGA

    2.Oracle深度学习笔记--内存架构之UGA 欢迎转载,转载请标明出处:  http://blog.csdn.net/notbaron/article/details/50558136 UGA是回 ...

  7. adg oracle,【学习笔记】Oracle ADG搭建与配置 windows平台11G ADG搭建与测试

    [学习笔记]Oracle ADG搭建与配置 windows平台11G ADG搭建与测试 时间:2016-10-26 20:09   来源:Oracle研究中心   作者:HTZ   点击: 次 天萃荷 ...

  8. oracle goldengate学习笔记,【学习笔记】Oracle goldengate monitor使用笔记

    天萃荷净 Oracle研究中心学习笔记:分享一篇关于Oracle数据库goldengate monitor的使用笔记. 本站文章除注明转载外,均为本站原创: 转载自love wife & lo ...

  9. 34.Oracle深度学习笔记——12C的AWR初步解读

    34.Oracle深度学习笔记--12C的AWR初步解读 关于AWR,蛤蟆也经常看.因为经常看别人给出的建议,很难有深刻体会.对此,计划花费几个晚上时间好好体会一把并记录下来.此处以单实例为例.列出目 ...

最新文章

  1. 图解当前最强语言模型BERT:NLP是如何攻克迁移学习的?
  2. 福州大学计算机组成原理试题,2016年福州大学计算机专业基础C复试之计算机组成原理复试笔试最后押题五套卷...
  3. spring+hibernate+struts整合(1)
  4. Spring Batch中的块处理
  5. arkit技术介绍_面向移动AR的触觉技术:如何以“触摸”感增强ARKit应用
  6. 网页怎么向服务器请求数据,网页怎么向服务器请求数据库
  7. Laravel学习笔记四-数据库迁移和模型文件
  8. SQL Server高级查询之子查询(单行子查询)
  9. MOSS中删除绑定到List上的Eventhandler
  10. spring的前后台数据传输。
  11. Java Web(一) Servlet详解!!
  12. 直播http-flv原理
  13. mysql怎么创建blog_「MySQL创建与删除数据库」- 海风纷飞Blog
  14. Elasticsearch聚合学习之二:区间聚合
  15. zip文件类型如何恢复系统默认值--右键->打开方式中 无 “资源管理器”选项
  16. Windows笔记本移动热点打不开
  17. 基于Kappa-mu/M分布的联合多用户分集与并行中继继选择RF/FSO系统性能研究
  18. 金蝶软件工具集4.0
  19. 关于网站中图片排名优化的技巧是?
  20. 亚像素边缘定位技术概论

热门文章

  1. 我对2019年人工智能行业发展的预测
  2. 2017 人工智能+内容生产研究报告
  3. 深度学习入门指北——从硬件到软件
  4. Tensorflow— saver_restore
  5. Tensorflow—非线形回归
  6. 求高维方阵的绝对值最大特征值的方法:幂法(幂迭代)。
  7. 最让青年科学家们困惑的 10 个问题,是什么?
  8. 区分真实模式的两个标准
  9. 智慧城市产业图谱(2020年)
  10. 实现计算机界“大满贯”,芮勇博士再获技术成就大奖