before insert or update or delete on T for each row
begin
??? null;
end;
/
create or replace trigger before_insert_update_delete
after insert or update or delete on T for each row
begin
??? null;
end;
/
觸 發(fā)器(trigger)是個(gè)特殊的存儲(chǔ)過(guò)程,它的執(zhí)行不是由程序調(diào)用,也不是手工啟動(dòng),而是由個(gè)事件來(lái)觸發(fā),比如當(dāng)對(duì)一個(gè)表進(jìn)行操作( insert,delete, update)時(shí)就會(huì)激活它執(zhí)行。觸發(fā)器經(jīng)常用于加強(qiáng)數(shù)據(jù)的完整性約束和業(yè)務(wù)規(guī)則等。 觸發(fā)器可以從 DBA_TRIGGERS ,USER_TRIGGERS 數(shù)據(jù)字典中查到。
觸發(fā)器可以查詢其他表,而且可以包含復(fù)雜的 SQL 語(yǔ)句。它們主要用于強(qiáng)制服從復(fù)雜的業(yè)務(wù)規(guī)則或要求。例如,您可以根據(jù)客戶當(dāng)前的帳戶狀態(tài),控制是否允許插入新訂單。
觸發(fā)器也可用于強(qiáng)制引用完整性,以便在多個(gè)表中添加、更新或刪除行時(shí),保留在這些表之間所定義的關(guān)系。然而,強(qiáng)制引用完整性的最好方法是在相關(guān)表中定義主鍵和外鍵約束。如果使用數(shù)據(jù)庫(kù)關(guān)系圖,則可以在表之間創(chuàng)建關(guān)系以自動(dòng)創(chuàng)建外鍵約束。
最基本的觸發(fā)器是針對(duì)表的Insert、Update、Delete這三種操作來(lái)的。觸發(fā)器可以建立在表上,也可以建立在視圖上。建立在表上的觸發(fā) 器會(huì)在表內(nèi)容發(fā)生改變時(shí)觸發(fā)。建立在視圖上的觸發(fā)器會(huì)在視圖內(nèi)容改變時(shí)觸發(fā)。注意,視圖觸發(fā)器僅會(huì)在明確對(duì)視圖進(jìn)行操作的SQL語(yǔ)句執(zhí)行時(shí)才會(huì)觸發(fā),當(dāng)基 本表的內(nèi)容發(fā)生改變而引起視圖內(nèi)容變化時(shí),不會(huì)觸發(fā)視圖觸發(fā)器。
是特定事件出現(xiàn)的時(shí)候,自動(dòng)執(zhí)行的代碼塊。類似于存儲(chǔ)過(guò)程,但是用戶不能直接調(diào)用他們。
功能:
1、 允許/限制對(duì)表的修改
2、 自動(dòng)生成派生列,比如自增字段
3、 強(qiáng)制數(shù)據(jù)一致性
4、 提供審計(jì)和日志記錄
5、 防止無(wú)效的事務(wù)處理
6、 啟用復(fù)雜的業(yè)務(wù)邏輯
開始
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ā)語(yǔ)句
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ā)語(yǔ)句
比如:
表或視圖上的DML語(yǔ)句
DDL語(yǔ)句
數(shù)據(jù)庫(kù)關(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
說(shuō)明:
1、 無(wú)論是否規(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;
主體很簡(jiǎn)單,就是將更新后的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,
);
select commission_pct from employees where employee_id=12345;
觸發(fā)器不會(huì)通知用戶,便改變了用戶的輸入值。
觸發(fā)器類型:
1、 語(yǔ)句觸發(fā)器
2、 行觸發(fā)器
3、 INSTEAD OF 觸發(fā)器
4、 系統(tǒng)條件觸發(fā)器
5、 用戶事件觸發(fā)器
1、 語(yǔ)句觸發(fā)器
是 在表上或者某些情況下的視圖上執(zhí)行的特定語(yǔ)句或者語(yǔ)句組上的觸發(fā)器。能夠與INSERT、UPDATE、DELETE或者組合上進(jìn)行關(guān)聯(lián)。但是無(wú)論使用什 么樣的組合,各個(gè)語(yǔ)句觸發(fā)器都只會(huì)針對(duì)指定語(yǔ)句激活一次。比如,無(wú)論update多少行,也只會(huì)調(diào)用一次update語(yǔ)句觸發(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表上建立語(yǔ)句觸發(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è)語(yǔ)句起作用?
即是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ā)器,以便記錄語(yǔ)句類型。
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
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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