黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

Oracle中觸發(fā)器的應(yīng)用

系統(tǒng) 2210 0
觸發(fā)器是指存放在數(shù)據(jù)庫中,并且被隱含執(zhí)行的存儲(chǔ)過程。當(dāng)發(fā)生特定事件時(shí),Oracle會(huì)自動(dòng)執(zhí)行觸發(fā)器的響應(yīng)代碼。



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



數(shù)據(jù)操縱語言(DML)觸發(fā)器:簡稱DML觸發(fā)器,是定義在表上的觸發(fā)器,創(chuàng)建在表上。

由DML事件引發(fā)的觸發(fā)器,編寫DML觸發(fā)器時(shí)的兩點(diǎn)要素是:

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

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



功能:
1、 允許/限制對(duì)表的修改
2、 自動(dòng)生成派生列,比如自增字段
3、 強(qiáng)制數(shù)據(jù)一致性
4、 提供審計(jì)和日志記錄
5、 防止無效的事務(wù)處理
6、 啟用復(fù)雜的業(yè)務(wù)邏輯



ORACLE產(chǎn)生數(shù)據(jù)庫觸發(fā)器的語法為:

  CREATE [OR REPLACE] TRIGGER 觸發(fā)器名



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



  ON 表名



  WHEN 觸發(fā)條件



  [FOR EACH ROW]



  DECLARE



  聲明部分



  BEGIN



  主體部分



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



  觸發(fā)器名:觸發(fā)器對(duì)象的名稱。由于觸發(fā)器是數(shù)據(jù)庫自動(dòng)執(zhí)行的,因此該名稱只是一個(gè)名稱,沒有實(shí)質(zhì)的用途。一個(gè)觸發(fā)器可由多個(gè)不同的數(shù)據(jù)操縱語言操作觸發(fā)。在觸發(fā)器中,可用INSERTING、DELETING、UPDATING謂詞來區(qū)別不同的數(shù)據(jù)操縱語言操作。這些謂詞可以在IF分支條件語句中作為判斷條件來使用。



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



  Before:表示在數(shù)據(jù)庫動(dòng)作之前觸發(fā)器執(zhí)行;在SQL語句的執(zhí)行過程中,如果存在行級(jí)BEFORE觸發(fā)器,則SQL語句在對(duì)每一行操作之前,都要先執(zhí)行一次行級(jí)BEFORE觸發(fā)器,然后才對(duì)行進(jìn)行操作。如果存在行級(jí)AFTER觸發(fā)器,則SQL語句在對(duì)每一行操作之后,都要再執(zhí)行一次行級(jí)AFTER觸發(fā)器。



  after:表示在數(shù)據(jù)庫動(dòng)作之后出發(fā)器執(zhí)行。如果存在語句級(jí)AFTER觸發(fā)器,則在SQL語句執(zhí)行完畢后,要最后執(zhí)行一次語句級(jí)AFTER觸發(fā)器。



  觸發(fā)事件:指明哪些數(shù)據(jù)庫動(dòng)作會(huì)觸發(fā)此觸發(fā)器,指INSERT、DELETE或UPDATE事件,事件可以并行出現(xiàn),中間用OR連接;



  insert:數(shù)據(jù)庫插入會(huì)觸發(fā)此觸發(fā)器;



  update:數(shù)據(jù)庫修改會(huì)觸發(fā)此觸發(fā)器;



  delete:數(shù)據(jù)庫刪除會(huì)觸發(fā)此觸發(fā)器。



  表 名:數(shù)據(jù)庫觸發(fā)器所在的表。



  for each row:表示觸發(fā)器為行級(jí)觸發(fā)器,省略則為語句級(jí)觸發(fā)器,對(duì)表的每一行觸發(fā)器執(zhí)行一次。



  觸發(fā)器的創(chuàng)建者或具有DROP ANY TIRGGER系統(tǒng)權(quán)限的人才能刪除觸發(fā)器。刪除觸發(fā)器的語法如下:



  DROP TIRGGER 觸發(fā)器名



  可以通過命令設(shè)置觸發(fā)器的可用狀態(tài),使其暫時(shí)關(guān)閉或重新打開,即當(dāng)觸發(fā)器暫時(shí)不用時(shí),可以將其置成無效狀態(tài),在使用時(shí)重新打開。該命令語法如下:



  ALTER TRIGGER 觸發(fā)器名 {DISABLE|ENABLE}



  其中,DISABLE表示使觸發(fā)器失效,ENABLE表示使觸發(fā)器生效。



  同存儲(chǔ)過程類似,觸發(fā)器可以用SHOW ERRORS 檢查編譯錯(cuò)誤。



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



  觸發(fā)器的作用



  觸發(fā)器的主要作用就是其能夠?qū)崿F(xiàn)由主鍵和外鍵所不能保證的復(fù)雜的參照完整性和數(shù)據(jù)的一致性。除此之外,觸發(fā)器還有其它許多不同的功能:



  (1) 強(qiáng)化約束(Enforce restriction)



  觸發(fā)器能夠?qū)崿F(xiàn)比CHECK 語句更為復(fù)雜的約束。



  (2) 跟蹤變化Auditing changes



  觸發(fā)器可以偵測(cè)數(shù)據(jù)庫內(nèi)的操作,從而不允許數(shù)據(jù)庫中未經(jīng)許可的指定更新和變化。



  (3) 級(jí)聯(lián)運(yùn)行(Cascaded operation)。



  觸發(fā)器可以偵測(cè)數(shù)據(jù)庫內(nèi)的操作,并自動(dòng)地級(jí)聯(lián)影響整個(gè)數(shù)據(jù)庫的各項(xiàng)內(nèi)容。例如,某個(gè)表上的觸發(fā)器中包含有對(duì)另外一個(gè)表的數(shù)據(jù)操作(如刪除,更新,插入)而該操作又導(dǎo)致該表上觸發(fā)器被觸發(fā)。



  (4) 存儲(chǔ)過程的調(diào)用(Stored procedure invocation)。



  為了響應(yīng)數(shù)據(jù)庫更新觸,發(fā)器可以調(diào)用一個(gè)或多個(gè)存儲(chǔ)過程,甚至可以通過外部過程的調(diào)用而在DBMS( 數(shù)據(jù)庫管理系統(tǒng))本身之外進(jìn)行操作。



  由此可見,觸發(fā)器可以解決高級(jí)形式的業(yè)務(wù)規(guī)則或復(fù)雜行為限制以及實(shí)現(xiàn)定制記錄等一些方面的問題。例如,觸發(fā)器能夠找出某一表在數(shù)據(jù)修改前后狀態(tài)發(fā)生的差異,并根據(jù)這種差異執(zhí)行一定的處理。此外一個(gè)表的同一類型(INSERT、 UPDATE、 DELETE)的多個(gè)觸發(fā)器能夠?qū)ν环N數(shù)據(jù)操作采取多種不同的處理。



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



????? 當(dāng)運(yùn)行觸發(fā)器時(shí),系統(tǒng)處理的大部分時(shí)間花費(fèi)在參照其它表的這一處理上,因?yàn)檫@些表既不在內(nèi)存中也不在數(shù)據(jù)庫設(shè)備上,而刪除表和插入表總是位于內(nèi)存中。可見觸發(fā)器所參照的其它表的位置決定了操作要花費(fèi)的時(shí)間長短。





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



開始
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;
/

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

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

2、 觸發(fā)語句
比如:
表或視圖上的DML語句
DDL語句
數(shù)據(jù)庫關(guān)閉或啟動(dòng),startup shutdown 等等
before insert or update
? of department_id
? on employees
referencing old as old_value
???? new as new_value
for each row

說明:
1、 無論是否規(guī)定了department_id ,對(duì)employees表進(jìn)行insert的時(shí)候
2、 對(duì)employees表的department_id列進(jìn)行update的時(shí)候

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

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

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

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

觸發(fā):
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;

觸發(fā)器不會(huì)通知用戶,便改變了用戶的輸入值。



觸發(fā)器類型:
1、 語句觸發(fā)器
2、 行觸發(fā)器
3、 INSTEAD OF 觸發(fā)器
4、 系統(tǒng)條件觸發(fā)器
5、 用戶事件觸發(fā)器



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

DELETE或者組合上進(jìn)行關(guān)聯(lián)。但是無論使用什么樣的組合,各個(gè)語句觸發(fā)器都只會(huì)針對(duì)指定語句激活一次

。比如,無論update多少行,也只會(huì)調(diào)用一次update語句觸發(fā)器。

例子:
需要對(duì)在表上進(jìn)行DML操作的用戶進(jìn)行安全檢查,看是否具有合適的特權(quán)。
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表

[試驗(yàn)]
對(duì)修改表的時(shí)間、人物進(jìn)行日志記錄。

1、 建立試驗(yàn)表
create table employees_copy as select *from hr.employees

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

3、 在employees_copy表上建立語句觸發(fā)器,在觸發(fā)器中填充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、 測(cè)試
update employees_copy set salary= salary*1.1;

select *from employess_log;

5、 確定是哪個(gè)語句起作用?
即是INSERT/UPDATE/DELETE中的哪一個(gè)觸發(fā)了觸發(fā)器?
可以在觸發(fā)器中使用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;

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

2、 修改觸發(fā)器,以便記錄語句類型。
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、 測(cè)試
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、 行觸發(fā)器
是指為受到影響的各個(gè)行激活的觸發(fā)器,定義與語句觸發(fā)器類似,有以下兩個(gè)例外:
1、 定義語句中包含F(xiàn)OR EACH ROW子句
2、 在BEFORE……FOR EACH ROW觸發(fā)器中,用戶可以引用受到影響的行值。
比如:

定義:
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 子句:
執(zhí)行DML語句之前的值的默認(rèn)名稱是 ld ,之后的值是 :new
insert 操作只有:new
delete 操作只有 ld
update 操作兩者都有

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

new的表時(shí)。
作用不很大。



[試驗(yàn)]:為主健生成自增序列號(hào)

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 觸發(fā)器更新視圖

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、 系統(tǒng)事件觸發(fā)器
系統(tǒng)事件:數(shù)據(jù)庫啟動(dòng)、關(guān)閉,服務(wù)器錯(cuò)誤

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


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

RENAME / TRUNCATE / LOGOFF

例子:記錄刪除對(duì)象

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

2.觸發(fā)器
create or replace trigger log_drop_trigger
before drop on donny.schema
begin
insert into droped_objects values(
? ora_dict_obj_name,? -- 與觸發(fā)器相關(guān)的函數(shù)
? ora_dict_obj_type,
? sysdate);
end;
/


3. 測(cè)試
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


禁用和啟用觸發(fā)器
alter trigger <trigger_name> disable;
alter trigger <trigger_name> enable;

事務(wù)處理:
在觸發(fā)器中,不能使用commit / rollback
因?yàn)閐dl語句具有隱式的commit,所以也不允許使用

視圖:dba_triggers

Oracle中觸發(fā)器的應(yīng)用


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論