码迷,mamicode.com
首页 > 数据库 > 详细

Oracle-触发器

时间:2016-03-03 00:04:36      阅读:405      评论:0      收藏:0      [点我收藏+]

标签:

触发器可以看做一种“特殊”的存储过程,它定义了一些与数据库相关事件(INSERT,UPDATE,CREATE)发生时应执行的“功能代码块”,通常用于管理复杂的完整性约束,或监控对表的修改,或通知其他程序,甚至可以实现对数据的审计功能。

触发事件:能够引起触发器运行的操作被称为“触发事件”,如执行DML(INSERT,UPDATE,DELETE),DDL(CREATE,ALTER.DROP);引发数据库系统事件(系统启动或退出,产生异常错误);引发用户事件(登陆或退出数据库操作)

根据触发器的触发事件和触发器的执行情况,Oracle所支持的触发器分为一下5种类型:

1行级触发器:当DML语句对每一行数据进行操作时都会引起该触发器的运行

2语句级触发器:无论DML语句影响多上行数据,其所引起的触发器仅执行一次

3替换触发器:该触发器是定义在视图上的,而不是定义在表上,它是用来替换所使用实际语句的触发器

4用户事件触发器:与DDL操作或用户登陆、退出数据库事件相关的触发器。

5.系统事件触发器:指Oracle数据库系统的事件中进行触发的触发器,如Oracle实例的启动与关闭

 

语句级触发器

例子:在SCOTT模式下,创建dept_log数据表,并在其中定义两个字段,分别用来存储操作种类信息和操作日期:

create table dept_log
(
operate_tag varchar2(10),
operate_tiem date
);

创建一个关于emp表的语句级触发器,将用户对dept表的操作信息保存到dept_log表中:

create or replace trigger tri_dept
before insert or update or delete
on dept
declare
var_tag varchar2(10);
begin
if inserting then
var_tag:=‘插入‘;
elsif updating then
var_tag:=‘修改‘;
elsif deleting then
var_tag:=‘删除‘;
end if;
insert into dept_log
values(var_tag,sysdate);
end tri_dept;
/

 

执行触发器,也就是触发这些事件(insert,update,delete);之后再查看dept_log表就可以观察到结果

 

行级触发器

例子 :在SCOTT模式下,创建一个用于存储商品种类的数据表,其中包括商品序号列和商品名称列:

create table goods(

id int primary key,

good_name varchar2(50));

创建一个序列:

create sequence seq_id;

创建一个触发器,用于为goods表的id赋值

create or replace trigger tri_insert_good
before insert
on goods
for each row
begin
select seq_id.nextval
into :new.id
from dual;
end;
/

 

:new.id--列标识符

  有两种列标识符,

  原值标识符:--:old.id --一般在update delete

  新值标识符:--:new.id--一般在update insert

触发该触发器:

可以通过插入语句 insert into goods(good_name) values(‘苹果‘);

同时用insert into goods(id,good_name)values (9,‘葡萄‘);

然后再查询该表即可知道是否,自动插入了id

但是第二条记录的id,还是会顺序增长,那是因为,触发器将seq_id的nextval值赋给了:new.id,并且nextval属性值是连续不间断的

 

替换触发器

例子:首先创建一个视图

(首先该用户要有创建视图的权限,切换到system ,grant create view to scott)

create view view_emp_dept
as
select empno,ename,dept.deptno,dname,job,hiredate from emp,dept
where emp.deptno=dept.deptno;

注意:在没有创建“替换触发器”时,试图向该视图中插入数据,是会有错误的ORA-01776:无法通过连接视图修改多个基表

创建一个关于view_emp_dept视图的替换触发器,在该触发器的主体中实现向emp表和dept表中插入两行相互关联的数据

create or replace trigger tri_insert_view
instead of insert
on view_emp_dept
for each row
declare
row_dept dept%rowtype;
begin
select * into row_dept from dept where deptno=:new.deptno;
if sql%notfound then

insert into dept(deptno,dname) values(:new.deptno,:new.dname);
end if;
insert into emp(empno,ename,deptno,job,hiredate) values
(:new.empno,:new.ename,:new.deptno,:new.job,:new.hiredate);
end tri_insert_view;
/

触发该触发器:

insert into view_emp_dept(empno,ename,deptno,dname,job,hiredate)

values(8888,‘东方‘,10,‘ACCOUTNTING‘,‘CASHIER‘,sysdate);

这样,便可以插入一条记录到视图;

但是,如果这个deptno不在dept表中,那么会在dept表中插入相关记录,但是,测试时,却出现了错误

技术分享

技术分享

 

 

用户事件触发器

因进行DDL操作或用户登录、退出操作而引起运行的一种触发器,比如CREATE,ALTER,DROP,ANALYZE,COMMENT,GRANT,REVOKE,RENAME,TRUNCATE,SUSPEND,LOGON ,LOGOFF

创建一个日志信息表,用于保存DDL操作的信息,包括数据对象,数据对象类型,操作行为,操作用户,操作日期

create table ddl_oper_log
(
db_obj_name varchar2(20),
db_obj_type varchar2(20),
oper_action varchar2(20),
oper_user varchar2(20),
oper_date date);

关于scott用户的DDL操作(CREATE,ALTER,DROP),创建一个触发器,然后将DDL操作的相关信息插入到ddl_oper_log日志表中

create or replace trigger tri_ddl_oper
before create or alter or drop
on scott.schema
begin
insert into ddl_oper_log values(
ora_dict_obj_name,--获取DDL操作对象的名称
ora_dict_obj_type,--获取DDL操作所对应的数据库对象的类型
ora_sysevent,--获取触发器的系统事件名称
ora_login_user,--获取登陆用户名
sysdate);
end;
/

触发触发器:

create,alter,drop 然后再select * from ddl_oper_log;

 

Oracle-触发器

标签:

原文地址:http://www.cnblogs.com/xcnblog3035/p/5236877.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!