使用觸發器的目的數據庫
構建實驗表app
SQL> drop table d purge;
表已刪除。
SQL> drop table e purge;
表已刪除。
SQL> create table d as select * from dept;
表已建立。
SQL> create table e as select * from emp;
表已建立。
spa
建立觸發器 it
SQL> create or replace trigger d_update
after delete or update of deptno on d
for each row --行級觸發
begin
if (updating and :old.deptno != :new.deptno)
then update e
set deptno =:new.deptno
where deptno=:old.deptno;
end if; --當d表的部門號修改的時候e表的部門號也相應的修改
if deleting then
delete e where deptno=:old.deptno;
end if; --當d表的部門號修改的時候e表的部門號也相應的修改
end;
/
觸發器已建立
io
驗證觸發器的狀態table
SQL> select trigger_name,status from user_triggers;
TRIGGER_NAME STATUS
------------------------------ --------
D_UPDATE ENABLED 登錄
改變觸發器的狀態date
禁用某個觸發器select
SQL> alter trigger d_update disable;
觸發器已更改
SQL> select trigger_name,status from user_triggers;
TRIGGER_NAME STATUS
------------------------------ --------
D_UPDATE DISABLED
error
禁用某個表上全部的觸發器
SQL> alter table d disable all triggers;
表已更改。
SQL> select * from d;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
刪除觸發器
SQL> drop trigger d_update;
觸發器已刪除。
SQL> select trigger_name,status from user_triggers;
未選定行
驗證d_update的功能
SQL> update d set deptno=50 where deptno=30;
已更新 1 行。
SQL> select empno,ename from e;
EMPNO ENAME
---------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7839 KING
7844 TURNER
7900 JAMES
7902 FORD
7934 MILLER
已選擇12行。
SQL> select * from d;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
50 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> delete d where deptno=20;
已刪除 1 行。
SQL> select empno,ename,deptno from e;
EMPNO ENAME DEPTNO
---------- ---------- ----------
7499 ALLEN 50
7521 WARD 50
7654 MARTIN 50
7698 BLAKE 50
7782 CLARK 10
7839 KING 10
7844 TURNER 50
7900 JAMES 50
7934 MILLER 10
已選擇9行。
SQL> select * from d;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
50 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> commit;
部門編號爲20的數據都不存在了。
觸發器的類型
行級觸發
語句集觸發
什麼時候觸發
before
在條件運行以前,執行觸發器
after
在條件運行後,執行觸發器
instead of
替代觸發,做用在視圖上
禁止對錶e的sal進行修改
SQL> create or replace trigger e_update
2 before update of sal on e
3 begin
4 if updating then
5 raise_application_error(-20001,'工資不能被改動');
6 end if;
7 end;
8 /
觸發器已建立
SQL> select ename,sal from e;
ENAME SAL
---------- ----------
ALLEN 1600
WARD 1250
MARTIN 1250
BLAKE 2850
CLARK 2450
KING 5000
TURNER 1500
JAMES 950
MILLER 1300
已選擇9行。
SQL> update e set sal=2000 where ename='ALLEN';
update e set sal=2000 where ename='ALLEN'
*
第 1 行出現錯誤:
ORA-20001: 工資不能被改動
ORA-06512: 在 "SCOTT.E_UPDATE", line 3
ORA-04088: 觸發器 'SCOTT.E_UPDATE' 執行過程當中出錯
保存老值和新的值
SQL> DROP TABLE T1;
表已刪除。
SQL> CREATE TABLE T1 AS SELECT sal old_value,sal new_value from emp where 0=9;
表已建立。
SQL> create or replace trigger trg1
2 before insert or update of sal on emp
3 for each row
4 begin
5 insert into t1 values(:old.sal,:new.sal);
6 end;
7 /
觸發器已建立
SQL> select * from t1;
未選定行
SQL> update emp set sal=sal+1;
已更新12行。
SQL> commit;
提交完成。
SQL> select * from t1;
OLD_VALUE NEW_VALUE
---------- ----------
800 801
1600 1601
1250 1251
2975 2976
1250 1251
2850 2851
2450 2451
5000 5001
1500 1501
950 951
3000 3001
1300 1301
已選擇12行。
創建一個經過視圖來改基表的視圖v1
SQL> drop table e1;
表已刪除。
SQL> create table e1 as select * from emp;
表已建立。
SQL> drop view v1;
SQL> create view v1 as select distinct deptno from e1;
視圖已建立。
試圖修改v1時報錯
SQL> update v1 set deptno=50 where deptno=10;
update v1 set deptno=50 where deptno=10
*
第 1 行出現錯誤:
ORA-01732: 此視圖的數據操縱操做非法
創建一個替代觸發器,當修改v1時會自動修改基表
SQL> create or replace trigger trigger_instead_of
2 instead of insert or update or delete on v1
3 begin
4 if updating then
5 update e1 set deptno=:new.deptno where deptno=:old.deptno;
6 end if;
7 end;
8 /
觸發器已建立
SQL> update v1 set deptno=50 where deptno=10;
已更新 1 行。
SQL> select ename,deptno from e1;
ENAME DEPTNO
---------- ----------
SMITH 20
ALLEN 30
WARD 30
JONES 20
MARTIN 30
BLAKE 30
CLARK 50
KING 50
TURNER 30
JAMES 30
FORD 20
ENAME DEPTNO
---------- ----------
MILLER 50
已選擇12行。
SQL> select * from v1;
DEPTNO
----------
30
20
50
創建一個登陸的審計觸發器
SQL> drop table login_table;
SQL> create table login_table(user_id varchar2(15),log_date date,action varchar2(15));
表已建立。
SQL> create or replace trigger logon_trig
2 after logon on schema --on schema方式是隻記錄當前的用戶行爲
3 begin
4 insert into login_table(user_id,log_date,action)
5 values(USER,SYSDATE,'Logging on');
6 end;
7 /
觸發器已建立
SQL> create or replace trigger logoff_trig
2 before logoff on schema
3 begin
4 insert into login_table(user_id,log_date,action)
5 values(USER,SYSDATE,'Logging off');
6 end;
7 /
觸發器已建立
SQL> conn scott/scott
已鏈接。
SQL> select * from login_table;
USER_ID LOG_DATE ACTION
--------------- -------------- ---------------
SCOTT 17-6月 -13 Logging off
SCOTT 17-6月 -13 Logging on
SQL> conn zhengyu/zhengyu
已鏈接。
SQL> conn scott/scott
已鏈接。
SQL> select * from login_table;USER_ID LOG_DATE ACTION --------------- -------------- --------------- SCOTT 17-6月 -13 Logging off SCOTT 17-6月 -13 Logging on SCOTT 17-6月 -13 Logging on SCOTT 17-6月 -13 Logging off SQL> select user_id,to_char(log_date,'yyyy/mm/dd:hh24:mi:ss') log_date,action from login_table;USER_ID LOG_DATE ACTION --------------- ------------------- --------------- SCOTT 2013/06/17:17:04:55 Logging off SCOTT 2013/06/17:17:05:42 Logging on SCOTT 2013/06/17:17:04:56 Logging on SCOTT 2013/06/17:17:05:33 Logging off SQL> drop trigger logon_trig;觸發器已刪除。SQL> drop trigger logoff_trig;觸發器已刪除。