Oracle 觸發器 資料日誌

2021-10-07 09:50:59 字數 3456 閱讀 6890

觸發器就是乙個特殊的儲存過程,與普通儲存過程不同的是,觸發器是由事件來隱式啟動的,而且不接受引數指定。oracle事件指的是對資料庫表的dml操作、ddl操作以及對資料庫的操作事件(例如資料庫啟動與關閉,異常錯誤)

dml觸發器:建立在表上,由表的dml操作觸發

ddl觸發器:建立在資料庫或模式上,由ddl操作觸發

insteadof觸發器:建立在檢視上,用於替代dml操作(oracle中不能直接對由兩個以上的表建立的檢視進行操作,所以可以使用insteadof觸發器對檢視進行操作)

系統觸發器:建立在資料庫或模式上,由資料庫事件觸發

dml觸發器:

create [ or replace ] trigger [ schema. ]trigger

delete | insert | update [ of column [, column ]... ]

[ or ]...

on [ schema. ]table | [ nested table nested_table_column of ] [ schema. ] view

[ referencing ]

[ for each row ]

[ when (condition) ]

;

其中:

ddl觸發器

create [ or replace ] trigger [ schema. ]trigger

on [ when (condition) ]

;

其中:

提供乙個工作中使用的用於記錄資料重複日誌的例項

建立資料表

create table t_base_table

建立日誌表

create t_table_data_log

建立觸發器

create or place trigger tr_base_table_duplication

before insert | update

on t_base_table

for each row

declare

-- 自定義異常number_duplication(-20001)

number_duplication exception;

pragma exception_init (number_duplication, -20001);

-- 開啟自治事務

pragma autonomous_transaction;

-- 定義欄位v_count用於獲取相同編碼的記錄數

v_count number(5);

begin

-- 跳過暫存資料

if (:new.fstatus = 0) then

return;

end if;

-- 針對update操作

case when updating then

-- 從資料表t_base_table查詢編碼重複,id不同且非暫存狀態的記錄數置入v_count

select count(1)

into v_count

from t_base_table

where fnumber = :new.fnumber

and fid <> :new.fid

and fstatus <> 0;

if (v_count > 0) then

-- 已存在相同編碼的記錄,往表t_table_data_log插入資料變更前後的資訊

-- 同時記錄為更新操作(update),並記錄更新時間

insert into t_table_data_log(fid, fnumber_new, fstatus_new, fdesc_new,

fnumber_old, fstatus_old, fdesc_old)

select :new.fid, 'update', sysdate, :new.fnumber, :new.fstatus, :new.fdesc,

:old.fnumber, :old.fstatus, :old.fdesc

from dual;

-- 提交插入日誌的事務

commit;

-- 丟擲number_duplication異常

end if;

-- 針對insert操作

when inserting then

-- 從資料表t_base_table查詢編碼重複,非暫存狀態的記錄數置入v_count

select count(1)

into v_count

from t_base_table

where fnumber = :new.fnumber

and fstatus <> 0;

if (v_count > 0) then

-- 已存在相同編碼的記錄,往表t_table_data_log插入資料變更前後的資訊

-- 同時記錄為插入操作(insert),並記錄更新時間

insert into t_table_data_log(fid, fnumber_new, fstatus_new, fdesc_new)

select :new.fid, 'update', sysdate, :new.fnumber, :new.fstatus, :new.fdesc

from dual;

-- 提交插入日誌的事務

commit;

-- 丟擲number_duplication異常

end if;

end case;

exception

-- 捕獲異常number_duplication,說明存在重複編碼,再次丟擲該異常給業務**

when number_duplication then

-- 捕獲其他異常,說明出現非可控的資料庫錯誤,插入日誌的事務無法成功提交

-- 回滾事務並丟擲重複編碼的異常給業務**

when others then

rollback;

commit;

end tr_base_table_duplication;

功能說明:在資料表做新增或更新操作前判斷是否存在編碼重複(或其他不方便直接增加的資料約束)的記錄,記錄該操作資訊及被運算元據的變更前後資料作為後續跟蹤的資料依據。

邏輯說明:資料表新增或更新前,先查詢記錄判斷是否需要拒絕該記錄的變更(根據業務約束決定),若需要拒絕,記錄該操作日誌,並拋出自定義的資料庫異常給上層邏輯。在觸發器外部捕獲異常,自定義的資料庫異常需要重新上拋,否則就是日誌操作引起的異常,此時需要回滾觸發器事務並上拋異常。

關鍵說明:pragma autonomous_transaction,這個觸發器的關鍵操作在於開啟了oracle自治事務,使得觸發器可以在新的事務中查詢dml操作的表記錄,同時該事務是與父事務隔離的,需要使用者自行提交事務且父事務的回滾不影響該事務的提交。

ORACLE觸發器 行級觸發器

行級觸發器 本章介紹行級觸發器機制。大部分例子以insert出發器給出,行級觸發器可從insert update delete語句觸發。1 介紹 觸發器是儲存在資料庫已編譯的儲存過程,使用的語言是pl sql,用編寫儲存過程一樣的方式編寫和編譯觸發器。下面在sql plus會話中建立和示例乙個簡單的...

Oracle觸發器介紹 行級觸發器

行級觸發器 本章介紹行級觸發器機制。大部分例子以insert出發器給出,行級觸發器可從insert update delete語句觸發。1 介紹 觸 髮器是儲存在資料庫已編譯的儲存過程,使用的語言是pl sql,用編寫儲存過程一樣的方式編寫和編譯觸發器。下面在sql plus會話中建立和示例一 個簡...

Oracle觸發器簡介 建立 使用觸發器

觸發器類似與儲存過程,都是為了實現特殊功能而執行的 塊。觸發器不允許使用者顯示傳遞引數,不能夠返回引數值,不允許使用者呼叫觸發器。觸發器只是在oracle合適的時間自動呼叫,非常類似於面向程式設計中的 觸發器按照觸發事件型別 物件不同分為 語句觸發器,行觸發器,instead of觸發器,系統事件觸...