定義: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)
- )
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
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');
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;
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');
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 sc_view
- select * from stu
select * from stu
- select * from course
select * from course
創建了view的trigger以後,可以直接通過添加wiew表單的數據來實現其他關聯表的處理。。
2)
- insert into stu values(6,'eric');
insert into stu values(6,'eric');
- insert into course values(6,'95');
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','[email protected]','15902701688',sysdate,2000,.12);
- insert into employees values(empl_seq.nextval,'justin','williams','[email protected]','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;
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','[email protected]','15902701688',sysdate,2000,.12);
insert into employees values(empl_seq.nextval,'justin','williams','[email protected]','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 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 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 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
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,所以也不允許使用