Oracle觸發器用法例項詳解
本文例項講述了Oracle觸發器用法。分享給大家供大家參考,具體如下:
一、觸發器簡介
觸發器的定義就是說某個條件成立的時候,觸發器裡面所定義的語句就會被自動的執行。因此觸發器不需要人為的去呼叫,也不能呼叫。然後,觸發器的觸發條件其實在你定義的時候就已經設定好了。這裡面需要說明一下,觸發器可以分為語句級觸發器和行級觸發器。詳細的介紹可以參考網上的資料,簡單的說就是語句級的觸發器可以在某些語句執行前或執行後被觸發。而行級觸發器則是在定義的了觸發的表中的行資料改變時就會被觸發一次。
具體舉例:
1、 在一個表中定義的語句級的觸發器,當這個表被刪除時,程式就會自動執行觸發器裡面定義的操作過程。這個就是刪除表的操作就是觸發器執行的條件了。
2、 在一個表中定義了行級的觸發器,那當這個表中一行資料發生變化的時候,比如刪除了一行記錄,那觸發器也會被自動執行了。
二、觸發器語法
觸發器的語法:
?1 2 3 4 5 6 |
create
[ or replace ] tigger 觸發器名 觸發時間 觸發事件
on
表名
[ for
each row]
begin
pl/sql語句
end
|
其中:
觸發器名:觸發器物件的名稱。由於觸發器是資料庫自動執行的,因此該名稱只是一個名稱,沒有實質的用途。
觸發時間:指明觸發器何時執行,該值可取:
before:表示在資料庫動作之前觸發器執行;
after:表示在資料庫動作之後觸發器執行。
觸發事件:指明哪些資料庫動作會觸發此觸發器:
insert:資料庫插入會觸發此觸發器;
update:資料庫修改會觸發此觸發器;
delete
表 名:資料庫觸發器所在的表。
for each row:對錶的每一行觸發器執行一次。如果沒有這一選項,則只對整個表執行一次。
觸發器能實現如下功能:
功能:
1、 允許/限制對錶的修改
2、 自動生成派生列,比如自增欄位
3、 強制資料一致性
4、 提供審計和日誌記錄
5、 防止無效的事務處理
6、 啟用複雜的業務邏輯
舉例
1)、下面的觸發器在更新表tb_emp之前觸發,目的是不允許在週末修改表:
?1 2 3 4 5 6 7 8 |
create
or replace trigger
auth_secure before insert
or update
or DELETE
on
tb_emp
begin
IF(to_char(sysdate, 'DY' )= '星期日' )
THEN
RAISE_APPLICATION_ERROR(-20600, '不能在週末修改表tb_emp' );
END
IF;
END ;
/
|
2)、使用觸發器實現序號自增
建立一個測試表:
?1 2 3 4 5 |
create
table tab_user(
id number(11)
primary key ,
username
varchar (50),
password
varchar (50)
);
|
建立一個序列:
建立一個觸發器:
?1 2 3 4 5 6 7 8 9 |
CREATE
OR REPLACE TRIGGER
MY_TGR
BEFORE
INSERT ON
TAB_USER
FOR
EACH ROW --對錶的每一行觸發器執行一次
DECLARE
NEXT_ID NUMBER;
BEGIN
SELECT
MY_SEQ.NEXTVAL INTO
NEXT_ID FROM
DUAL;
:NEW.ID := NEXT_ID;
--:NEW表示新插入的那條記錄
END ;
|
向表插入資料:
?1 2 3 4 |
insert
into tab_user(username, password )
values ( 'admin' , 'admin' );
insert
into tab_user(username, password )
values ( 'fgz' , 'fgz' );
insert
into tab_user(username, password )
values ( 'test' , 'test' );
COMMIT ;
|
查詢表結果:SELECT * FROM TAB_USER;
3)、當用戶對test表執行DML語句時,將相關資訊記錄到日誌表
?1 2 3 4 5 6 7 8 9 10 11 12 13 |
--建立測試表
CREATE
TABLE test(
t_id NUMBER(4),
t_name VARCHAR2(20),
t_age NUMBER(2),
t_sex
CHAR
);
--建立記錄測試表
CREATE
TABLE test_log(
l_user VARCHAR2(15),
l_type VARCHAR2(15),
l_date VARCHAR2(30)
);
|
建立觸發器:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
--建立觸發器
CREATE
OR REPLACE TRIGGER
TEST_TRIGGER
AFTER
DELETE OR
INSERT OR UPDATE
ON TEST
DECLARE
V_TYPE TEST_LOG.L_TYPE%TYPE;
BEGIN
IF INSERTING
THEN
--INSERT觸發
V_TYPE :=
'INSERT' ;
DBMS_OUTPUT.PUT_LINE( '記錄已經成功插入,並已記錄到日誌' );
ELSIF UPDATING
THEN
--UPDATE觸發
V_TYPE :=
'UPDATE' ;
DBMS_OUTPUT.PUT_LINE( '記錄已經成功更新,並已記錄到日誌' );
ELSIF DELETING
THEN
--DELETE觸發
V_TYPE :=
'DELETE' ;
DBMS_OUTPUT.PUT_LINE( '記錄已經成功刪除,並已記錄到日誌' );
END
IF;
INSERT
INTO TEST_LOG
VALUES
( USER , V_TYPE, TO_CHAR(SYSDATE,
'yyyy-mm-dd hh24:mi:ss' ));
--USER表示當前使用者名稱
END ;
/
--下面我們來分別執行DML語句
INSERT
INTO test VALUES (101, 'zhao' ,22, 'M' );
UPDATE
test SET t_age = 30
WHERE t_id = 101;
DELETE
test WHERE t_id = 101;
--然後檢視效果
SELECT
* FROM test;
SELECT
* FROM test_log;
|
執行結果如下:
3)、建立觸發器,它將對映emp表中每個部門的總人數和總工資
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
--建立對映表
CREATE
TABLE dept_sal AS
SELECT
deptno, COUNT (empno) total_emp,
SUM (sal) total_sal
FROM
scott.emp
GROUP
BY deptno;
--建立觸發器
CREATE
OR REPLACE TRIGGER
EMP_INFO
AFTER
INSERT OR
UPDATE OR DELETE
ON scott.EMP
DECLARE
CURSOR
CUR_EMP IS
SELECT
DEPTNO, COUNT (EMPNO)
AS TOTAL_EMP,
SUM (SAL) AS
TOTAL_SAL FROM
scott.EMP GROUP
BY DEPTNO;
BEGIN
DELETE
DEPT_SAL; --觸發時首先刪除對映表資訊
FOR
V_EMP IN
CUR_EMP LOOP
--DBMS_OUTPUT.PUT_LINE(v_emp.deptno || v_emp.total_emp || v_emp.total_sal);
--插入資料
INSERT
INTO DEPT_SAL
VALUES
(V_EMP.DEPTNO, V_EMP.TOTAL_EMP, V_EMP.TOTAL_SAL);
END
LOOP;
END ;
--對emp表進行DML操作
INSERT
INTO emp(empno,deptno,sal) VALUES ( '123' , '10' ,10000);
SELECT
* FROM dept_sal;
DELETE
EMP WHERE empno=123;
SELECT
* FROM dept_sal;
|
顯示結果如下:
4)、建立觸發器,用來記錄表的刪除資料
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
--建立表
CREATE
TABLE employee(
id VARCHAR2(4)
NOT NULL ,
name
VARCHAR2(15) NOT
NULL ,
age NUMBER(2)
NOT NULL ,
sex
CHAR NOT
NULL
);
--插入資料
INSERT
INTO employee VALUES ( 'e101' , 'zhao' ,23, 'M' );
INSERT
INTO employee VALUES ( 'e102' , 'jian' ,21, 'F' );
--建立記錄表(包含資料記錄)
CREATE
TABLE old_employee AS
SELECT * FROM
employee;
--建立觸發器
CREATE
OR REPLACE TRIGGER
TIG_OLD_EMP
AFTER
DELETE ON
EMPLOYEE
FOR
EACH ROW --語句級觸發,即每一行觸發一次
BEGIN
INSERT
INTO OLD_EMPLOYEE
VALUES (:OLD.ID, :OLD. NAME , :OLD.AGE, :OLD.SEX);
--:old代表舊值
END ;
/
--下面進行測試
DELETE
employee;
SELECT
* FROM old_employee;
|
5)、建立觸發器,利用檢視插入資料
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
--建立表
CREATE
TABLE tab1 (tid NUMBER(4) PRIMARY
KEY ,tname VARCHAR2(20),tage NUMBER(2));
CREATE
TABLE tab2 (tid NUMBER(4),ttel VARCHAR2(15),tadr VARCHAR2(30));
--插入資料
INSERT
INTO tab1 VALUES (101, 'zhao' ,22);
INSERT
INTO tab1 VALUES (102, 'yang' ,20);
INSERT
INTO tab2 VALUES (101, '13761512841' , 'AnHuiSuZhou' );
INSERT
INTO tab2 VALUES (102, '13563258514' , 'AnHuiSuZhou' );
--建立檢視連線兩張表
CREATE
OR REPLACE VIEW
tab_view AS
SELECT tab1.tid,tname,ttel,tadr FROM
tab1,tab2 WHERE
tab1.tid = tab2.tid;
--建立觸發器
CREATE
OR REPLACE TRIGGER
TAB_TRIGGER
INSTEAD
OF INSERT
ON TAB_VIEW
BEGIN
INSERT
INTO TAB1 (TID, TNAME)
VALUES (:NEW.TID, :NEW.TNAME);
INSERT
INTO TAB2 (TTEL, TADR)
VALUES (:NEW.TTEL, :NEW.TADR);
END ;
/
--現在就可以利用檢視插入資料
INSERT
INTO tab_view VALUES (106, 'ljq' , '13886681288' , 'beijing' );
--查詢
SELECT
* FROM tab_view;
SELECT
* FROM tab1;
SELECT
* FROM tab2;
|
6)、建立觸發器,比較emp表中更新的工資
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
--建立觸發器
set
serveroutput on ;
CREATE
OR REPLACE TRIGGER
SAL_EMP
BEFORE
UPDATE ON
EMP
FOR
EACH ROW
BEGIN
IF :OLD.SAL > :NEW.SAL
THEN
DBMS_OUTPUT.PUT_LINE( '工資減少' );
ELSIF :OLD.SAL < :NEW.SAL
THEN
DBMS_OUTPUT.PUT_LINE( '工資增加' );
ELSE
DBMS_OUTPUT.PUT_LINE( '工資未作任何變動' );
END
IF;
DBMS_OUTPUT.PUT_LINE( '更新前工資 :'
|| :OLD.SAL);
DBMS_OUTPUT.PUT_LINE( '更新後工資 :'
|| :NEW.SAL);
END ;
/
--執行UPDATE檢視效果
UPDATE
emp SET sal = 3000
WHERE empno =
'7788' ;
|
執行結果如下:
7)、建立觸發器,將操作CREATE、DROP儲存在log_info表
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
--建立表
CREATE
TABLE log_info(
manager_user VARCHAR2(15),
manager_date VARCHAR2(15),
manager_type VARCHAR2(15),
obj_name VARCHAR2(15),
obj_type VARCHAR2(15)
);
--建立觸發器
set
serveroutput on ;
CREATE
OR REPLACE TRIGGER
TRIG_LOG_INFO
AFTER
CREATE OR
DROP ON SCHEMA
BEGIN
INSERT
INTO LOG_INFO
VALUES
( USER ,
SYSDATE,
SYS.DICTIONARY_OBJ_NAME,
SYS.DICTIONARY_OBJ_OWNER,
SYS.DICTIONARY_OBJ_TYPE);
END ;
/
--測試語句
CREATE
TABLE a(id NUMBER);
CREATE
TYPE aa AS OBJECT(id NUMBER);
DROP
TABLE a;
DROP
TYPE aa;
--檢視效果
SELECT
* FROM log_info;
--相關資料字典-----------------------------------------------------
SELECT
* FROM USER_TRIGGERS;
--必須以DBA身份登陸才能使用此資料字典
SELECT
* FROM ALL_TRIGGERS; SELECT
* FROM
DBA_TRIGGERS;
--啟用和禁用
ALTER
TRIGGER trigger_name DISABLE;
ALTER
TRIGGER trigger_name ENABLE;
|
希望本文所述對大家Oracle資料庫程式設計有所幫助。
相關推薦
Oracle觸發器用法例項詳解
本文例項講述了Oracle觸發器用法。分享給大家供大家參考,具體如下: 一、觸發器簡介 觸發器的定義就是說某個條件成立的時候,觸發器裡面所定義的語句就會被自動的執行。因此觸發器不需要人為的去呼叫,也不能呼叫。然後,觸發器的觸發條件其實在你定義的時候就已經設定好了。這裡面需
javascript中this用法例項詳解
JavaScript中的this含義非常豐富,它可以是全域性物件,當前物件或者是任意物件,這都取決於函式的呼叫方式。函式有以下幾種呼叫方式:作為物件方法呼叫、作為函式呼叫、作為建構函式呼叫、apply或call呼叫。 物件方法呼叫 作為物件方法呼叫的時候,this會被繫結到該物件。 ?
js事件監聽器用法例項詳解
本文例項講述了js事件監聽器用法。分享給大家供大家參考。具體分析如下: 1、當同一個物件使用.onclick的寫法觸發多個方法的時候,後一個方法會把前一個方法覆蓋掉,也就是說,在物件的onclick事件發生時,只會執行最後繫結的方法。而用事件監聽則不會有覆蓋的現象,每個繫結的事件都會被執行。
vue 元件高階用法例項詳解
一、遞迴元件 元件在它的模板內可以遞迴地呼叫自己, 只要給元件設定name 的選項就可以了。 示例如下: <div id="app19"> <my-component19 :count="1"></my-component19> </
mysql觸發器trigger 例項詳解
MySQL好像從5.0.2版本就開始支援觸發器的功能了,本次部落格就來介紹一下觸發器,首先還是談下概念性的東西吧: 什麼是觸發器 觸發器是與表有關的資料庫物件,在滿足定義條件時觸發,並執行觸發器中定義的語句集合。觸發器的這種特性可以協助應用在資料庫端確保資料的完整性。
資料庫工作筆記012---mysql觸發器trigger 例項詳解_保證資料庫完整性還是不錯的
mysql的觸發器,可以挺好的保證資料庫的資料的完整性,這個還是不錯的 JAVA技術交流QQ群:170933152 比如: 我一個表中的資料有變化,那麼與之關聯的幾個表可以通過觸發器來實現同步 --------
MySQL欄位自增長AUTO_INCREMENT用法例項詳解
之前有碰到過開發同事指出一張InnoDB表的自增列 AUTO_INCREMENT 值莫明的變大,由於這張表是通過mysqldump匯出匯入的。 問題排查: 1、首先,查看錶表義的sql部分的 auto_increment 值部分是正常,所以排除是匯入表問題所引起的;2、最後,經過溝通了解懷疑是插入時
Python多程序併發(multiprocessing)用法例項詳解
python多執行緒的限制python多執行緒有個討厭的限制,全域性直譯器鎖(global interpreter lock),這個鎖的意思是任一時間只能有一個執行緒使用直譯器,跟單cpu跑多個程式一個意思,大家都是輪著用的,這叫“併發”,不是“並行”。手冊上的解釋是為了保證
C++ pair的用法例項詳解(結構體模板應用初探)
1 pair的應用(結構體模板)pair是將2個數據組合成一個數據,當需要這樣的需求時就可以使用pair,如stl中的map就是將key和value放在一起來儲存。另一個應用是,當一個函式需要返回2個數據的時候,可以選擇pair。標頭檔案:#include<utilit
Ajax用法例項詳解
本文例項講述了jQuery學習筆記之Ajax用法。分享給大家供大家參考,具體如下: 一、Ajax請求 1、jQuery.ajax(options) 通過 HTTP 請求載入遠端資料。jQuery 底層 AJAX 實現。簡單易用的高層實現見 .get,.post 等。
PHP單例模式和工廠模式用法例項詳解
設計模式是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。毫無疑問,設計模式於己於他人於系統都是多贏的;設計模式使程式碼編制真正工程化;設計模式是軟體工程的基石脈絡,如同大廈的結
JavaScript中window.open用法例項詳解
本文較為詳細的分析了JavaScript中window.open用法。分享給大家供大家參考。具體如下: 複製程式碼 程式碼如下: <script LANGUAGE="javascript"> window.open ('page.html', 'newwind
SQL建立觸發器以及觸發器的使用例項+詳解
MySQL的觸發器使用例項: 解決 觸發器被觸發後,向表裡插入資料時判斷該條記錄是否存在,如果存在則更新,不存在則插入 的問題 首先,宣告一下 mysql 中寫的sql執行語句全部在 begin &nbs
oracle 建立表空間詳解、例項
建立臨時表空間----->建立表空間---->建立使用者指定表空間----->授權 --查詢表空間 select * from dba_tablespaces --查詢表空間路徑 select * from dba_data_file
mysql觸發器new old 詳解 真例項子
mysql觸發器new old: "NEW . column_name"或者"OLD . column_name".這樣在技術上處理(NEW | OLD . column_name)新和舊 的列名屬於建立了過渡變數("transition variables")。
java中List的用法和例項詳解
的用法List包括List介面以及List介面的所有實現類。因為List介面實現了Collection介面,所以List介面擁有Collection介面提供的所有常用方法,又因為List是列表型別,所以List介面還提供了一些適合於自身的常用方法,如表1所示。表1 List介面定義的常用方法及功能從表1可以看
Oracle expdp/impdp 用法例子 詳解 舉例 例子 他的這篇文章沒有辦法寫出來 要這麼改
在之前的blog: Oracle 10g Data Pump Expdp/Impdp 詳解 exp/imp 與 expdp/impdp 對比及使用中的一些優化事項 中對資料泵這塊的理論知識有一些說明,但是沒有實際操作的例子。 所以在這裡就對expdp/im
Linux top命令的用法詳細詳解
command load 命令 技術分享 服務 範圍 web服務器 睡眠狀態 打開 查看多核CPU命令mpstat -P ALL 和 sar -P ALL 說明:sar -P ALL > aaa.txt 重定向輸出內容到文件 aaa.txt top命令經
oracle pctfree和pctused詳解
blank 可用 htm post alt lock tables span 重新 一、建立表時候,註意PCTFREE參數的作用 PCTFREE:為一個塊保留的空間百分比,表示數據塊在什麽情況下可以被insert,默認是10,表示當數據塊的可用空間低於
oracle常用函數詳解(詳細)
sub 最後一天 run -1 fonts ase 必須 顯示 分享 作者:紅旗飄揚 Oracle SQL 提供了用於執行特定操作的專用函數。這些函數大大增強了 SQL 語言的功能。函數可以接受零個或者多個輸入參數,並返回一個輸出結果。 oracle 數據庫中主要使用兩種