亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Oracle中觸發器的應用

系統 1771 0
觸發器是指存放在數據庫中,并且被隱含執行的存儲過程。當發生特定事件時,Oracle會自動執行觸發器的響應代碼。



觸發器的種類可劃分為4種:1.數據操縱語言(DML)觸發器、2.替代(INSTEAD OF)觸發器、3.數據定義語言(DDL)觸發器、4.數據庫事件觸發器。



數據操縱語言(DML)觸發器:簡稱DML觸發器,是定義在表上的觸發器,創建在表上。

由DML事件引發的觸發器,編寫DML觸發器時的兩點要素是:

1.確定觸發的表,即在其上定義觸發器的表。

2.確定觸發的事件,DML觸發器的觸發事件有INSERT、UPDATE和DELETE三種;替代觸發器,簡稱INSTEAD OF觸發器,創建在視圖上,用來替換對視圖進行的刪除、插入和修改操作; 數據定義語言(DDL)觸發器,簡稱DDL觸發器,定義在模式上,觸發事件是數據對象的創建和修改;數據庫事件觸發器,定義在整個數據庫或模式上,觸發事件是數據庫事件.



功能:
1、 允許/限制對表的修改
2、 自動生成派生列,比如自增字段
3、 強制數據一致性
4、 提供審計和日志記錄
5、 防止無效的事務處理
6、 啟用復雜的業務邏輯



ORACLE產生數據庫觸發器的語法為:

  CREATE [OR REPLACE] TRIGGER 觸發器名



  {BEFORE|AFTER|INSTEAD OF} 觸發事件1 [OR 觸發事件2...]



  ON 表名



  WHEN 觸發條件



  [FOR EACH ROW]



  DECLARE



  聲明部分



  BEGIN



  主體部分



  END;
###StudyGet_Info_Pagination_SIGN###
??? 其中:



  觸發器名:觸發器對象的名稱。由于觸發器是數據庫自動執行的,因此該名稱只是一個名稱,沒有實質的用途。一個觸發器可由多個不同的數據操縱語言操作觸發。在觸發器中,可用INSERTING、DELETING、UPDATING謂詞來區別不同的數據操縱語言操作。這些謂詞可以在IF分支條件語句中作為判斷條件來使用。



  觸發時間:指明觸發器何時執行,該值可取, 觸發的時間有BEFORE和AFTER兩種,分別表示觸發動作發生在DML語句執行之前和語句執行之后。確定觸發級別,有語句級觸發器和行級觸發器兩種。語句級觸發器表示SQL語句只觸發一次觸發器,行級觸發器表示SQL語句影響的每一行都要觸發一次。



  Before:表示在數據庫動作之前觸發器執行;在SQL語句的執行過程中,如果存在行級BEFORE觸發器,則SQL語句在對每一行操作之前,都要先執行一次行級BEFORE觸發器,然后才對行進行操作。如果存在行級AFTER觸發器,則SQL語句在對每一行操作之后,都要再執行一次行級AFTER觸發器。



  after:表示在數據庫動作之后出發器執行。如果存在語句級AFTER觸發器,則在SQL語句執行完畢后,要最后執行一次語句級AFTER觸發器。



  觸發事件:指明哪些數據庫動作會觸發此觸發器,指INSERT、DELETE或UPDATE事件,事件可以并行出現,中間用OR連接;



  insert:數據庫插入會觸發此觸發器;



  update:數據庫修改會觸發此觸發器;



  delete:數據庫刪除會觸發此觸發器。



  表 名:數據庫觸發器所在的表。



  for each row:表示觸發器為行級觸發器,省略則為語句級觸發器,對表的每一行觸發器執行一次。



  觸發器的創建者或具有DROP ANY TIRGGER系統權限的人才能刪除觸發器。刪除觸發器的語法如下:



  DROP TIRGGER 觸發器名



  可以通過命令設置觸發器的可用狀態,使其暫時關閉或重新打開,即當觸發器暫時不用時,可以將其置成無效狀態,在使用時重新打開。該命令語法如下:



  ALTER TRIGGER 觸發器名 {DISABLE|ENABLE}



  其中,DISABLE表示使觸發器失效,ENABLE表示使觸發器生效。



  同存儲過程類似,觸發器可以用SHOW ERRORS 檢查編譯錯誤。



  如果有多個觸發器被定義成為相同時間、相同事件觸發,且最后定義的觸發器是有效的,則最后定義的觸發器被觸發,其他觸發器不執行。觸發器體內禁止使用COMMIT、ROLLBACK、SAVEPOINT語句,也禁止直接或間接地調用含有上述語句的存儲過程。定義一個觸發器時要考慮上述多種情況,并根據具體的需要來決定觸發器的種類。



  觸發器的作用



  觸發器的主要作用就是其能夠實現由主鍵和外鍵所不能保證的復雜的參照完整性和數據的一致性。除此之外,觸發器還有其它許多不同的功能:



  (1) 強化約束(Enforce restriction)



  觸發器能夠實現比CHECK 語句更為復雜的約束。



  (2) 跟蹤變化Auditing changes



  觸發器可以偵測數據庫內的操作,從而不允許數據庫中未經許可的指定更新和變化。



  (3) 級聯運行(Cascaded operation)。



  觸發器可以偵測數據庫內的操作,并自動地級聯影響整個數據庫的各項內容。例如,某個表上的觸發器中包含有對另外一個表的數據操作(如刪除,更新,插入)而該操作又導致該表上觸發器被觸發。



  (4) 存儲過程的調用(Stored procedure invocation)。



  為了響應數據庫更新觸,發器可以調用一個或多個存儲過程,甚至可以通過外部過程的調用而在DBMS( 數據庫管理系統)本身之外進行操作。



  由此可見,觸發器可以解決高級形式的業務規則或復雜行為限制以及實現定制記錄等一些方面的問題。例如,觸發器能夠找出某一表在數據修改前后狀態發生的差異,并根據這種差異執行一定的處理。此外一個表的同一類型(INSERT、 UPDATE、 DELETE)的多個觸發器能夠對同一種數據操作采取多種不同的處理。



  總體而言,觸發器性能通常比較低。



????? 當運行觸發器時,系統處理的大部分時間花費在參照其它表的這一處理上,因為這些表既不在內存中也不在數據庫設備上,而刪除表和插入表總是位于內存中。可見觸發器所參照的其它表的位置決定了操作要花費的時間長短。





---------------------------------------------示例說明-----------------------------------------------------------------



開始
create trigger biufer_employees_department_id
before insert or update
? of department_id
? on employees
referencing old as old_value
???? new as new_value
for each row
when (new_value.department_id<>80 )
begin
:new_value.commission_pct :=0;
end;
/

觸發器的組成部分:
1、 觸發器名稱
2、 觸發語句
3、 觸發器限制
4、 觸發操作

1、 觸發器名稱
create trigger biufer_employees_department_id
命名習慣:
biufer(before insert update for each row)
employees 表名
department_id 列名

2、 觸發語句
比如:
表或視圖上的DML語句
DDL語句
數據庫關閉或啟動,startup shutdown 等等
before insert or update
? of department_id
? on employees
referencing old as old_value
???? new as new_value
for each row

說明:
1、 無論是否規定了department_id ,對employees表進行insert的時候
2、 對employees表的department_id列進行update的時候

3、 觸發器限制
when (new_value.department_id<>80 )

限制不是必須的。此例表示如果列department_id不等于80的時候,觸發器就會執行。
其中的new_value是代表跟新之后的值。

4、 觸發操作
是觸發器的主體
begin
:new_value.commission_pct :=0;
end;

主體很簡單,就是將更新后的commission_pct列置為0

觸發:
insert into employees(employee_id,
last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct )
values( 12345,’Chen’,’Donny’, sysdate, 12, ‘donny@hotmail.com’,60,10000,.25);

select commission_pct from employees where employee_id=12345;

觸發器不會通知用戶,便改變了用戶的輸入值。



觸發器類型:
1、 語句觸發器
2、 行觸發器
3、 INSTEAD OF 觸發器
4、 系統條件觸發器
5、 用戶事件觸發器



1、 語句觸發器
是在表上或者某些情況下的視圖上執行的特定語句或者語句組上的觸發器。能夠與INSERT、UPDATE、

DELETE或者組合上進行關聯。但是無論使用什么樣的組合,各個語句觸發器都只會針對指定語句激活一次

。比如,無論update多少行,也只會調用一次update語句觸發器。

例子:
需要對在表上進行DML操作的用戶進行安全檢查,看是否具有合適的特權。
Create table foo(a number);

Create trigger biud_foo
Before insert or update or delete
? On foo
Begin
If user not in (‘DONNY’) then
? Raise_application_error(-20001, ‘You don’t have access to modify this table.’);
End if;
End;
/

即使SYS,SYSTEM用戶也不能修改foo表

[試驗]
對修改表的時間、人物進行日志記錄。

1、 建立試驗表
create table employees_copy as select *from hr.employees

2、 建立日志表
create table employees_log(
? who varchar2(30),
? when date);

3、 在employees_copy表上建立語句觸發器,在觸發器中填充employees_log 表。
Create or replace trigger biud_employee_copy
? Before insert or update or delete
?? On employees_copy
Begin
? Insert into employees_log(
?? Who,when)
? Values( user, sysdate);
?
End;
/
4、 測試
update employees_copy set salary= salary*1.1;

select *from employess_log;

5、 確定是哪個語句起作用?
即是INSERT/UPDATE/DELETE中的哪一個觸發了觸發器?
可以在觸發器中使用INSERTING / UPDATING / DELETING 條件謂詞,作判斷:
begin
? if inserting then
?? -----
? elsif updating then
?? -----
? elsif deleting then
?? ------
? end if;
end;

if updating(‘COL1’) or updating(‘COL2’) then
? ------
end if;

[試驗]
1、 修改日志表
alter table employees_log
? add (action varchar2(20));

2、 修改觸發器,以便記錄語句類型。
Create or replace trigger biud_employee_copy
? Before insert or update or delete
?? On employees_copy
Declare
? L_action employees_log.action%type;
Begin
? if inserting then
?? l_action:=’Insert’;
? elsif updating then
?? l_action:=’Update’;
? elsif deleting then
?? l_action:=’Delete’;
? else
?? raise_application_error(-20001,’You should never ever get this error.’);

? Insert into employees_log(
?? Who,action,when)
? Values( user, l_action,sysdate);
End;
/

3、 測試
insert into employees_copy( employee_id, last_name, email, hire_date, job_id)
values(12345,’Chen’,’Donny@hotmail’,sysdate,12);

select *from employees_log

update employees_copy set salary=50000 where employee_id = 12345;

2、 行觸發器
是指為受到影響的各個行激活的觸發器,定義與語句觸發器類似,有以下兩個例外:
1、 定義語句中包含FOR EACH ROW子句
2、 在BEFORE……FOR EACH ROW觸發器中,用戶可以引用受到影響的行值。
比如:

定義:
create trigger biufer_employees_department_id
before insert or update
? of department_id
? on employees_copy
referencing old as old_value
???? new as new_value
for each row
when (new_value.department_id<>80 )
begin
:new_value.commission_pct :=0;
end;
/

Referencing 子句:
執行DML語句之前的值的默認名稱是 ld ,之后的值是 :new
insert 操作只有:new
delete 操作只有 ld
update 操作兩者都有

referencing子句只是將new 和old重命名為new_value和old_value,目的是避免混淆。比如操作一個名為

new的表時。
作用不很大。



[試驗]:為主健生成自增序列號

drop table foo;
create table foo(id number, data varchar2(20));
create sequence foo_seq;

create or replace trigger bifer_foo_id_pk
before insert on foo
for each row
begin
select foo_seq.nextval into :new.id from dual;
end;
/

insert into foo(data) values(‘donny’);
insert into foo values(5,’Chen’);
select * from foo;

3、 INSTEAD OF 觸發器更新視圖

Create or replace view company_phone_book as
Select first_name||’, ’||last_name name, email, phone_number,
employee_id emp_id
From hr.employees;

嘗試更新email和name
update hr.company_phone_book
set name=’Chen1, Donny1’
where emp_id=100

create or replace trigger update_name_company_phone_book
INSTEAD OF
Update on hr.company_phone_book
Begin
Update hr.employees
? Set employee_id=:new.emp_id,
?? First_name=substr(:new.name, instr(:new.name,’,’)+2),
?? last_name= substr(:new.name,1,instr(:new.name,’,’)-1),
?? phone_number=:new.phone_number,
?? email=:new.email
where employee_id=:old.emp_id;
end;



4、 系統事件觸發器
系統事件:數據庫啟動、關閉,服務器錯誤

create trigger ad_startup
after startup
? on database
begin
-- do some stuff
end;
/


5、 用戶事件觸發器
用戶事件:用戶登陸、注銷,CREATE / ALTER / DROP / ANALYZE / AUDIT / GRANT / REVOKE /

RENAME / TRUNCATE / LOGOFF

例子:記錄刪除對象

1. 日志表
create table droped_objects(
object_name varchar2(30),
object_type varchar2(30),
dropped_on date);

2.觸發器
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;
/


3. 測試
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,所以也不允許使用

視圖:dba_triggers

Oracle中觸發器的應用


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 曰本亚洲欧洲色a在线 | 色婷婷国产 | 综合精品视频 | 天天躁日日躁狠狠躁综合 | videosex久久麻豆 | 亚洲精品乱码久久久久 | 亚洲精品亚洲人成在线 | 偷自拍视频区综合视频区 | 婷婷激情片 | 日韩第三页 | 青草久| 影音先锋在线亚洲精品推荐 | 最近中文日本字幕免费完整 | 97久久国语露脸精品对白 | 久久中文精品 | 全部免费特黄特色大片中国 | 亚洲精品一二三四 | 99久久国产综合精麻豆 | 国产成人h片视频在线观看 国产成人h综合亚洲欧美在线 | 午夜精品在线免费观看 | 亚洲精品色综合色在线观看 | 国产精品伦一区二区三级视频 | 四虎官网 | 久久久久亚洲 | 久久国产网 | 久草在线精品视频 | 中文国产成人久久精品小说 | 午夜性爽视频男人的天堂在线 | 中国产一级毛片 | 97色老99久久九九爱精品 | 国产二三区| 女人18一级毛片免费观看 | 四虎永久 | 日韩免费视频一区二区 | 欧美一级午夜免费视频你懂的 | www.亚洲一区二区三区 | 女性成人毛片a级 | 亚洲人成一区 | 777色狠狠一区二区三区香蕉 | 亚洲黄色高清视频 | 99re6在线视频免费精品 |