trigger instead of 事件觸發 用戶和系統

定義: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

Sql代碼 複製代碼 收藏代碼
  1. create table stu(   
  2. stu_id number(9) primary key,   
  3. stu_name varchar2(25)   
  4. )   
  5.   
  6. create table course(   
  7. c_id number(9) primary key,   
  8. grade varchar2(25),   
  9. foreign key (c_id) references stu(stu_id)   
  10. )  
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

Sql代碼 複製代碼 收藏代碼
  1. create view sc_view as    
  2. 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

Sql代碼 複製代碼 收藏代碼
  1. insert into sc_view values(5,'lily','75');  
insert into sc_view values(5,'lily','75');

結果:result:

 

 --step3  create a trigger

Sql代碼 複製代碼 收藏代碼
  1. create or replace trigger tri_sc_view   
  2. instead of insert on sc_view   
  3. begin  
  4. insert into stu values(:new.stu_id,:new.stu_name);   
  5. insert into course values(:new.stu_id,:new.grade);   
  6. 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)

Sql代碼 複製代碼 收藏代碼
  1. insert into sc_view values(1,'justin','88');   
  2. insert into sc_view values(2,'irs','70');   
  3. insert into sc_view values(3,'danile,'90);   
  4. insert into sc_view values(4,'tina,'75');   
  5. 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');

 結果:

Sql代碼 複製代碼 收藏代碼
  1. select * from sc_view  
select * from sc_view

 

  

Sql代碼 複製代碼 收藏代碼
  1. select * from stu  
select * from stu

 

 

Sql代碼 複製代碼 收藏代碼
  1. select * from course  
select * from course

 

 

創建了view的trigger以後,可以直接通過添加wiew表單的數據來實現其他關聯表的處理。。

 

2)

Sql代碼 複製代碼 收藏代碼
  1. insert into stu values(6,'eric');  
insert into stu values(6,'eric');

 

Sql代碼 複製代碼 收藏代碼
  1. insert into course values(6,'95');  
insert into course values(6,'95');

 

結果:

 

實際上是一起跟新的...

 

b)有關更新update的觸發器;

Sql代碼 複製代碼 收藏代碼
  1. select * from employees   
  2.   
  3. create sequence empl_seq;   
  4.   
  5. alter table employees drop(job_id,manger_id,department_id,dn)   
  6.   
  7. insert into employees values(empl_seq.nextval,'daniel','hwong','[email protected]','15902701688',sysdate,2000,.12);   
  8.   
  9. insert into employees values(empl_seq.nextval,'justin','williams','[email protected]','15902701114',sysdate,5000,.12);   
  10.   
  11. create or replace view tt_view as  
  12. select employees.first_name||','||employees.last_name v_name,employees.email,employees.phone_no,employees.employee_id from employees   
  13.   
  14. select * from tt_view   
  15.   
  16. update tt_view set v_name='justin2,william2'where employee_id=2   
  17. --執行彈出 oracl-01733此處不允許修改虛擬值--   
  18.   
  19. create or replace trigger tri_employ   
  20. instead of update on tt_view   
  21. begin  
  22. update employees set    
  23.                      employees.first_name=substr(:new.v_name,instr(:new.v_name,',')+1),   
  24.                      employees.last_name=substr(:new.v_name,1,instr(:new.v_name,',')-1),   
  25.                      employees.phone_no=:new.phone_no,   
  26.                      employees.email=:new.email   
  27.                      where employees.employee_id=:new.employee_id;   
  28. 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;

第二:用戶事件觸發器;

Sql代碼 複製代碼 收藏代碼
  1. create trigger ad_startup   
  2.  after startup   
  3.   on database  
  4. begin  
  5.  -- do some stuff   
  6. end;  
create trigger ad_startup
 after startup
  on database
begin
 -- do some stuff
end;

 第三:系統觸發器;

-----用戶事件:用戶登陸、註銷,CREATE / ALTER / DROP / ANALYZE / AUDIT / GRANT / REVOKE /
RENAME / TRUNCATE / LOGOFF

 

Sql代碼 複製代碼 收藏代碼
  1. create table droped_objects(   
  2.  object_name varchar2(30),   
  3.  object_type varchar2(30),   
  4.  dropped_on date);  
create table droped_objects(
 object_name varchar2(30),
 object_type varchar2(30),
 dropped_on date);

 

Sql代碼 複製代碼 收藏代碼
  1. create or replace trigger log_drop_trigger   
  2.  before drop on donny.schema  
  3. begin  
  4.  insert into droped_objects values(   
  5.   ora_dict_obj_name,  -- 與觸發器相關的函數   
  6.   ora_dict_obj_type,   
  7.   sysdate);   
  8. 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;

 

Sql代碼 複製代碼 收藏代碼
  1. create table drop_me(a number);   
  2. create view drop_me_view as select *from drop_me;   
  3. drop view drop_me_view;   
  4. drop table drop_me;   
  5. 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,所以也不允許使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章