定义:instead of
1) 基于view表单的处理可以在表和视图上指定一个instead of 触发器
2) 执行这种触发器可以代替原来的触发器,instead of 触发器扩展了视图跟新类型
3) 每一个表和视图只能有一个instead of 触发器
4) INSTEAD OF触发器被用于更新那些没有办法通过正常方式更新的视图
5) INSTEAD OF触发器的主要优点就是可以使不能更新的视图支持更新。基于多个表的视图必须使用。
6) INSTEAD OF触发器来支持多个表中数据的插入、更新和删除操作。
注:不能在带有with check option 定义的视图中创建INSTEAD OF触发器
第一:instead of 触发器:
a: 有关insert的触发时间的触发器
--step 1 create referenced table
create table stu(
stu_id number(9) primary key,
stu_name varchar2(25)
)
create table course(
c_id number(9) primary key,
grade varchar2(25),
foreign key (c_id) references stu(stu_id)
)
--step 2 create a view
create view sc_view as
select stu.stu_id,stu.stu_name,course.grade from stu,course where stu.stu_id=course.c_id
测试:testing insert one statement
insert into sc_view values(5,'lily','75');
结果:result:
--step3 create a trigger
create or replace trigger tri_sc_view
instead of insert on sc_view
begin
insert into stu values(:new.stu_id,:new.stu_name);
insert into course values(:new.stu_id,:new.grade);
end;
提示:很多人纠结为什么 插入 stu & course表中的:new.stu_id是一样了?其实new.stu_id只是一个数值而已,那这句语句分析insert into sc_view values(5,'lily','75'); :new.new.stu_id 就是5,:new.stu_name就是‘lily’,:new.grade就是‘75’。他们的产生是根据创建的视图表sc_view的到的。触发器的执行过程是,先遇到触发事件这里指:insert into sc_view values(5,'lily','75'); 然后产生想对应的:new.stu_id ,:new.stu_name,:new.grade。将这些值赋值给了触发器作用的表单;
执行语句:
1)
insert into sc_view values(1,'justin','88');
insert into sc_view values(2,'irs','70');
insert into sc_view values(3,'danile,'90);
insert into sc_view values(4,'tina,'75');
insert into sc_view values(5,'lily','75');
结果:
select * from sc_view
select * from stu
select * from course
创建了view的trigger以后,可以直接通过添加wiew表单的数据来实现其他关联表的处理。。
2)
insert into stu values(6,'eric');
insert into course values(6,'95');
结果:
实际上是一起跟新的...
b)有关更新update的触发器;
select * from employees
create sequence empl_seq;
alter table employees drop(job_id,manger_id,department_id,dn)
insert into employees values(empl_seq.nextval,'daniel','hwong','daniel@yahoo.com','15902701688',sysdate,2000,.12);
insert into employees values(empl_seq.nextval,'justin','williams','justin@yahoo.com','15902701114',sysdate,5000,.12);
create or replace view tt_view as
select employees.first_name||','||employees.last_name v_name,employees.email,employees.phone_no,employees.employee_id from employees
select * from tt_view
update tt_view set v_name='justin2,william2'where employee_id=2
--执行弹出 oracl-01733此处不允许修改虚拟值--
create or replace trigger tri_employ
instead of update on tt_view
begin
update employees set
employees.first_name=substr(:new.v_name,instr(:new.v_name,',')+1),
employees.last_name=substr(:new.v_name,1,instr(:new.v_name,',')-1),
employees.phone_no=:new.phone_no,
employees.email=:new.email
where employees.employee_id=:new.employee_id;
end;
第二:用户事件触发器;
create trigger ad_startup
after startup
on database
begin
-- do some stuff
end;
第三:系统触发器;
-----用户事件:用户登陆、注销,CREATE / ALTER / DROP / ANALYZE / AUDIT / GRANT / REVOKE /
RENAME / TRUNCATE / LOGOFF
create table droped_objects(
object_name varchar2(30),
object_type varchar2(30),
dropped_on date);
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;
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,所以也不允许使用