視圖trigger, instead of
我們知道如果一個view只是由一個table構成,那在view上做啥操作沒太多限制.如果view是由多個table組成那在view上做啥unpdate,insert,delete都會出錯.但有時又確實要做這些操作該咋辦呢.這就需要用到trigger,然後通過instead of關鍵字來指定一些替代操作.
舉個簡單例子,如果有view, my_view建立trigger如下
create or replace trigger my_view_trigger
instead of insert or update
on my_view
declare
insert into tmp(eno) values(:new.eno);
end;
當執行sql : insert into my_view(eno, name) values(88,'test');時觸發trigger.
不過view的instead of類型的trigger相對其他類型trigger有個特別的地方.從名字也可以看出來,可以替換掉了觸發它的sql的操作.也就是insert into my_view(eno, name) values(88,'test');這個sql本身的操作不會起作用了.只有trigger裡面的pl/sql語句塊才真正執行.
注意事項:
1.instead of 類型觸發器只能針對view建立,並且該view上不能有些check option(比如with check read only之類的),這以所這樣是防止不同的功能之間的衝突.假如是一個read only類型的view,那自然不能整出個trigger又可以做些DML操作了.
2.不能指定before或after選項,因為觸發trigger的sql實際上並不會執行,所以before或after就沒有啥意義了.
Database , Schema層級trigger
針對錶和視圖的Triggers可能開發人員用的多.針對database,schema的Trigger一般是DBA用的多點.
比如建立trigger每當schema上有DDL操作時觸發(針對錶或視圖的trigger只能針對DML操作,不能針對DDL操作).
舉個簡單的例子
CREATE OR REPLACE TRIGGER ddl_trigger
AFTER DDL ON SCHEMA
BEGIN
insert into tblog values(systimestamp,ora_sysevent, ora_login_user,
ora_dict_obj_type, ora_dict_obj_name);
END;
其中ora_login_user是登陸名,ora_dict_obj_type物件類型(比如表或視圖),ora_dict_obj_name是對象名字,比如表名或視圖名.你可能看到這些變數貌似沒在哪裡定義.實際上是oracle定義好的,你只要拿來用就行.
假如隨便用哪個使用者執行如下sql: create table tmp_tb(eno int); 就會觸發trigger.
不過貌似上面不能直接指定是具體的哪個schema,只能針對所有schema了啊.
假如使用者每次登陸時要做些記錄.那可以建立如下trigger
CREATE OR REPLACE TRIGGER logon_trigger
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO tblog VALUES (ora_login_user, ora_client_ip_address, systimestamp);
END ;
這裡的logon on database不是說資料庫啟動,而是每次串連一個session的時候.