oracle觸發器加條件判斷,如果某個字段,isnode=0,那么不執行下面的方法,數據如下:
create or replace trigger tr_basestation_insert_emp before insert on BJLT.BASESTATION REFERENCING NEW AS new_val OLD AS old_val --在這里設置名字,然后可引用新值,舊值 for each row when (new_val.isnode = 0) declare --local variables here begin insert into BSMS.BS_INFO@TOBSMS_BETTERY_LOCAL.REGRESS.RDBMS.DEV.US.ORACLE.COM(INFOID, INFONAME, GROUPID, ADDRESS, BUILDDATE, MAINTENANCER, TEL, TEMPERATURE, RECTIFIERCUR, OUTVOL, CREATETIME, SORTID, ONEOFFVOL, TWOOFFVOL, ISNODE, NODENUM, ONOFFPOWER, ONOFFPOWERMODEL, POWERA, POWERB, POWERC, POWEROUT, POWERACUR, POWERBCUR, POWERCCUR, POWERAVOL, POWERBVOL, POWERCVOL, DOOROPEN, HS, YANGAN, SHUIJIN, HONGWAI, KONGTIAO, VERID) values ('1','1','8a82fcd4-eba9-4f83-82d6-8ded897f3f10', '1',sysdate,'1', '1',0,'1', 1,sysdate,1, 1,1,1, 1,'1','1', -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1,-1, 1); end;
參考自:http://blog.csdn.net/weiwenhp/article/details/9179891
trigger和procedure,function類似,只不過它不能被顯示調用,只能被某個事件觸發然后oracle自動去調用.常用的一般 是針對一個表或視圖創建一個trigger,然后對表或視圖做某些操作時觸發trigger.當然除此之外還有,schema,database級別的 trigger.
什么樣的操作觸發trigger
常見的是DML(insert,update,delete) , DDL(create,alter,drop)語句.
不常見的是schema級別trigger在session連接或斷開時觸發.database級別trigger在系統啟動或退出時觸發.
你可能很容易發現如果是select查詢操作就沒法用到trigger,而有時可能我們想監測誰查看了一些敏感信息,此時只能用到一個叫FGA的東東,可以創建一個審計策略(可以看成加強版的trigger,FGA介紹詳見:http://blog.csdn.net/weiwenhp/article/details/7165660)
使用觸發器注意事項
1.觸發器不接受參數,一個表最多可有12個觸發器(觸發器類型剛好是12種),並且同一時間,同一事件,同一類型的觸發器只能有一個(保證觸發器操作不沖突嘛).
2.觸發器最大為32KB,由於大小受到限制自然也不能使用long,blob這樣的大變量.如果實在是有復雜的邏輯,要弄個很復雜的觸發器,可以通過procedure或function實現一部分功能,然后調用
3.因為觸發器實際上可以看作觸發語句的一部分.所以得遵循一些約束條件,比如不能有事務控制語句 (commit,rollback,savepoint),DDL語句.為啥子呢,這些特殊語句與一般sql語句的最主要區別是涉及到commit的問 題.所以如果觸發語句只是一般語句的話自然不能因為trigger的操作帶有commit這樣的特性了.
創建觸發器
針對表或視圖的觸發器格式如下:
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER }
{INSERT | DELETE | UPDATE [OF column [, column …]]}
[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]
ON [schema.]table_name | [schema.]view_name
[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]
[FOR EACH ROW ]
[WHEN condition]
PL/SQL_BLOCK | CALL procedure_name;
先來看一個簡單的,statement級別的trigger怎么創建.假如有表tb1,每insert一點就通過trigger在tblog中記錄一些信息.
create or replace trigger tb1_trigger
after insert on tb1
referencing new as new old as old
declare
v_info varchar2(100);
begin
v_info := "do a insert";
insert into tblog(info) values(v_info);
end;
trigger的創建中有個不太容易理解的內容:一針對row級別的trigger舊值新值問題
row級別trigger舊值新值
針對一個表或視圖創建trigger時分為statement級別與row級別的trigger.所謂statement級別是說一個sql語句觸發一次trigger,而如果是row級別則一個sql語句涉及到多行數據則trigger會被觸發多次.
而舊值就是指要更改的那一行數據在被改之前的值,新值就是用戶更新后值.假如表tt只有一列一行數據:88.然后用戶執行語句update tt set id = 99 where id = 88;
則舊值指88,新值指99.那你們可能會問用什么方式去得到舊值或新值啊.來舉例看下
假如有表tb(eno int); 和表tblog( info varchar2(100)); 假如在tb上創建trigger,tb每update一次則在tblog中記錄舊值就更改后的新值.
CREATE OR REPLACE TRIGGER tb_trigger
BEFORE UPDATE
ON tb
REFERENCING NEW AS new_val OLD AS old_val --在這里設置名字,然后可引用新值,舊值.如果不指定默認值為new ,old.可以通過:new或:old去引用
FOR EACH ROW
DECLARE
v_info varchar2(100);
BEGIN
v_info := 'old value:' ||to_char( :old_val.eno) || 'new value:' || to_char(:new_val.eno);
insert into tblog values(v_info);
END;
條件判斷
假如只有在涉及到某一行的操作時觸發trigger,假如該觸發器是針對updat,delete,insert都觸發的情形.咋整呢,自然是多用些when去判斷啊.
例如
CREATE OR REPLACE TRIGGER tb_trigger
BEFORE UPDATE or insert or delete
ON tb
REFERENCING NEW AS new_val OLD AS old_val --在這里設置名字,然后可引用新值,舊值
FOR EACH ROW
when (old_val.eno = 99)
DECLARE
v_info varchar2(100);
BEGIN
case
when updating then
v_info := 'old value:' ||to_char( :old_val.eno) || 'new value:' || to_char(:new_val.eno);
insert into tblog values(v_info);
when inserting then
null;
when deleting then
null;
end case;
END;