Oracle触发器(trigger):一般用法

php中文网
发布: 2016-06-07 17:30:15
原创
1184人浏览过

trigger和procedure,function类似,只不过它不能被显示调用,只能被某个事件触发然后oracle自动去调用.常用的一般是针对一个表或视

trigger和procedure,function类似,只不过它不能被显示调用,只能被某个事件触发然后oracle自动去调用.常用的一般是针对一个表或视图创建一个trigger,然后对表或视图做某些操作时触发trigger.当然除此之外还有,schema,database级别的trigger.

什么样的操作触发trigger

常见的是DML(insert,update,delete) , DDL(create,alter,drop)语句.

不常见的是schema级别trigger在session连接或断开时触发.database级别trigger在系统启动或退出时触发.

你可能很容易发现如果是select查询操作就没法用到trigger,而有时可能我们想监测谁查看了一些敏感信息,此时只能用到一个叫FGA的东东,可以创建一个审计策略(可以看成加强版的trigger,FGA介绍详见:  ) 

使用触发器注意事项

1.触发器不接受参数,一个表最多可有12个触发器(触发器类型刚好是12种),并且同一时间,同一事件,同一类型的触发器只能有一个(保证触发器操作不冲突嘛).

2.触发器最大为32KB,由于大小受到限制自然也不能使用long,blob这样的大变量.如果实在是有复杂的逻辑,要弄个很复杂的触发器,可以通过procedure或function实现一部分功能,然后调用

3.因为触发器实际上可以看作触发语句的一部分.所以得遵循一些约束条件,比如不能有事务控制语句(commit,rollback,savepoint),DDL语句.为啥子呢,这些特殊语句与一般sql语句的最主要区别是涉及到commit的问题.所以如果触发语句只是一般语句的话自然不能因为trigger的操作带有commit这样的特性了. 

创建触发器

针对表或视图的触发器格式如下: 

CREATE [OR REPLACE] TRIGGER trigger_name

{BEFORE | AFTER }

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

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

ON [schema.]table_name | [schema.]view_name

[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]

[FOR EACH ROW ]

[WHEN condition]

PL/SQL_BLOCK | CALL procedure_name;

 

先来看一个简单的,statement级别的trigger怎么创建.假如有表tb1,每insert一点就通过trigger在tblog中记录一些信息.

create or replace trigger tb1_trigger

after insert on tb1

referencing new as new old as old

 

declare

v_info varchar2(100);

begin

v_info := "do a insert";

insert into tblog(info) values(v_info);

end;

 

trigger的创建中有个不太容易理解的内容:一针对row级别的trigger旧值新值问题

row级别trigger旧值新值

针对一个表或视图创建trigger时分为statement级别与row级别的trigger.所谓statement级别是说一个sql语句触发一次trigger,而如果是row级别则一个sql语句涉及到多行数据则trigger会被触发多次.

而旧值就是指要更改的那一行数据在被改之前的值,新值就是用户更新后值.假如表tt只有一列一行数据:88.然后用户执行语句update tt set id = 99 where id = 88;

则旧值指88,新值指99.那你们可能会问用什么方式去得到旧值或新值啊.来举例看下

假如有表tb(eno int); 和表tblog( info varchar2(100)); 假如在tb上创建trigger,tb每update一次则在tblog中记录旧值就更改后的新值.

 

CREATE OR REPLACE TRIGGER tb_trigger

BEFORE UPDATE

Android游戏开发之旅 中文WORD版
Android游戏开发之旅 中文WORD版

本文档主要讲述的是Android游戏开发之旅;今天Android123开始新的Android游戏开发之旅系列,主要从控制方法(按键、轨迹球、触屏、重力感应、摄像头、话筒气流、光线亮度)、图形View(高效绘图技术如双缓冲)、音效(游戏音乐)以及最后的OpenGL ES(Java层)和NDK的OpenGL和J2ME游戏移植到Android方法,当然还有一些游戏实现惯用方法,比如地图编辑器,在Android OpenGL如何使用MD2文件,个部分讲述下Android游戏开发的过程最终实现一个比较完整的游戏引擎

Android游戏开发之旅 中文WORD版 0
查看详情 Android游戏开发之旅 中文WORD版

ON tb

REFERENCING NEW AS new_val OLD AS old_val --在这里设置名字,然后可引用新值,旧值.如果不指定默认值为new ,old.可以通过:new或:old去引用

FOR EACH ROW

DECLARE

v_info varchar2(100);

BEGIN

 

v_info := 'old value:' ||to_char( :old_val.eno) || 'new value:' || to_char(:new_val.eno);

insert into tblog values(v_info);

END;

条件判断

假如只有在涉及到某一行的操作时触发trigger,假如该触发器是针对updat,delete,insert都触发的情形.咋整呢,自然是多用些when去判断啊.

例如

CREATE OR REPLACE TRIGGER tb_trigger

BEFORE UPDATE or insert or delete

ON tb

REFERENCING NEW AS new_val OLD AS old_val --在这里设置名字,然后可引用新值,旧值

FOR EACH ROW

when (old_val.eno = 99)

DECLARE

v_info varchar2(100);

BEGIN

 

case

when updating then

v_info := 'old value:' ||to_char( :old_val.eno) || 'new value:' || to_char(:new_val.eno);

insert into tblog values(v_info);

 

when inserting then

null;

 

when deleting then

null;

 

end case;

END;

linux

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号