oracle的觸發器

--oracle_trigger.sql

觸發器是指被隱含執行的存儲過程,能夠用PL/SQL,java,c進行開發。

觸發器由觸發事件,觸發條件和觸發操做三部分組成。
(1)觸發事件
指引發觸發器被觸發的SQL語句,數據庫事件或者用戶事件。

具體觸發事件:
啓動和關閉數據庫實例
oracle錯誤消息
用戶登陸和斷開會話
特定表和視圖的DML操做
在任何方案上的DDL操做

(2)觸發條件(可選)
指使用when子句指定一個BOOLEAN表達式,當布爾表達式爲TRUE時,會自動執行觸發器相應代碼。


(3)觸發操做
指包含SQL語句和其餘執行代碼的PL/SQL塊。

限制條件:
1.觸發器代碼不能超過32K。
2.觸發器代碼中不能使用long or long raw數據類型。


###基於視圖的觸發器instead of觸發器


###DML觸發器包括語句觸發器和行觸發器

DML須要指定觸發時機(before|after),觸發事件(insert,update,delete),表名,觸發類型,觸發條件,觸發操做。

觸發時機:用於指定觸發器的觸發時間。before表示執行DML操做以前觸發觸發器。
觸發事件:用於指定致使觸發器執行DML操做。
表名:用於指定DML操做所對應的表。
觸發類型:用於指定當觸發事件發生以後,須要執行幾回觸發操做。
觸發條件:用於指定執行觸發器的條件,只有條件爲TRUE時纔會執行觸發器代碼。
觸發操做:用於指定觸發器執行代碼。


1.語句觸發器
當審計DML操做,或者確保DML操做安全執行時,能夠使用語句觸發器。語句觸發器不能記錄列數據的變化。

語法:
create or replace trigger trigger_name
timing event1 [or event2 or event3]
on table_name
pl/sql block;


(1)before語句觸發器
//禁止工做人員在週一改變僱員信息

create or replace trigger tr_change_emp
before insert or update or delete
on emp
begin
if to_char(sysdate,'DY','nls_date_language=AMERICAN') IN ('MON') then
--if to_char(sysdate,'DY','nls_date_language=''SIMPLIFIED CHINESE''') IN ('星期一') THEN
raise_application_error(-20001,'You can not change employee infor.');
end if;
end;

當觸發器中同時包含多個觸發事件時(insert,update,delete).區分具體的觸發事件,能夠使用3個爲此:
inserting,updating,deleting

create or replace trigger tr_change_emp
before insert or update or delete
on emp
begin
  if to_char(sysdate, 'DY', 'nls_date_language=AMERICAN') IN ('MON') then
  case when inserting then
    raise_application_error(-20001, 'You can not insert employee infor.');
    when updating then
    raise_application_error(-20002, 'You can not update employee infor.');
    when deleting then
    raise_application_error(-20003, 'You can not delete employee infor.');
    end case;
  end if;
end;



(2)after語句觸發器
//審計emp表上insert,update,delete操做次數

create table t_audit(names varchar2(30) not null primary key,insert_count number,update_count number,delete_count number,start_date date,end_date date);

create or replace trigger tr_audit_emp
after insert or update or delete on emp
declare

  v_tmp number;
begin
  select count(*) INTO v_tmp from t_audit where names = 'EMP';
  if v_tmp = 0 then
    insert into t_audit values ('EMP', 0, 0, 0, sysdate, null);
  end if;

  case
    when inserting then
      update t_audit
         set insert_count = insert_count + 1
       where names = 'EMP';
    
    when updating then
      update t_audit
         set update_count = update_count + 1
       where names = 'EMP';
    
    when deleting then
      update t_audit
         set delete_count = delete_count + 1
       where names = 'EMP';
    
  end case;

end;




2.行觸發器

行觸發器是指執行DML操做時,每做用一行就觸發一次的觸發器。審計數據變化時,能夠使用行觸發器。

語法:
create or replace trigger trigger_name
timing event1 [or event2 or event3]
on table_name
[reference OLD AS old|NEW AS new]
FOR EACH ROW
[when condition]
PL/SQL block;


reference:用於指定新,舊數據的方式。默認狀況下OLD修飾符引用舊數據,使用NEW修飾符引用新數據。

FOR EACH ROW:表示創建行觸發器


(1)before行觸發器
//確保僱員工資不低於其原有工資

create or replace trigger tr_update_sal
before update of sal on emp
for each row
begin

if :NEW.sal < :OLD.sal then
   raise_application_error(-20001,'salary up');
end if;

end;


(2)
//審計僱員工資的變化

create table t_audit_salary(enames varchar2(50),oldsal number(7,2),newsal number(7,2),create_date timestamp);

create or replace trigger tr_audit_salary
after update of sal on emp
for each row
declare
v_tmp number;
begin
select count(*) into v_tmp from t_audit_salary where enames=:old.ename;
if v_tmp =0 then
insert into t_audit_salary values(:old.ename,:old.sal,:new.sal,sysdate);
else
update t_audit_salary set oldsal=:old.sal,newsal=:new.sal,create_date =sysdate
where enames=:old.ename;
end  if;
end;
###系統事件觸發器
系統事件觸發器指基於oracle系統事件所創建的觸發器,提供了跟蹤系統內或數據庫變化的機制。

常見的系統事件屬性函數:
ora_client_ip_address:用於返回客戶端的IP地址。
ora_database_name:用於返回當前數據庫名。
ora_login_user:用於返回登陸用戶名。
ora_sysevent:用於返回觸發觸發器的系統事件名。


//記錄用戶登陸和退出
create table t_login(username varchar2(50),logon_date date,logoff_date date,address varchar2(15));

create or replace trigger tr_login
after logon on database
begin
insert into t_login(username,logon_date,address)
values(ora_login_user,sysdate,ora_client_ip_address);
end;

----

create or replace trigger tr_logoff
before logoff on database
begin
insert into t_login(username,logoff_date)
values(ora_login_user,sysdate);
end;


//記錄數據庫啓動和關閉

create table t_sysevent(events varchar2(50),create_date timestamp);


create or  replace trigger tr_startup
after startup on database
begin
insert into t_sysevent values(ora_sysevent,sysdate);
end;

create or replace trigger tr_shutdown
before shutdown on database
begin
insert into t_sysevent values(ora_sysevent,sysdate);
end;


###管理觸發器
select TRIGGER_NAME,table_name,status from user_triggers where table_name='EMP';

---禁止觸發器
alter trigger trigger_name disable;

---啓用觸發器
alter trigger TR_STARTUP enable;
java

相關文章
相關標籤/搜索