标签:
我们为什么用触发器呢?instead-of触发器(视图):当向一个由多个表联接成的视图作DML操作时,一般情况下是不允许的,这时候就可以用Instead-of触发器来解决这种问题(在触发器写代码分别对各表作相应DML操作),语法是这样的: create or replace trigger trigger_name instead of insert|update|delete on view_name for each row 下面以试验说明每一种触发器: SQL> select * from v$version where rownum=1; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production SQL> show user; USER 为 "HR"DML触发器:禁止用CREATE、ALTER、DROP、TRUNCATE命令操作HR用户的对象
SQL> create table t_trigger(username varchar2(10),ip varchar2(10),time date,term inal varchar2(10),event varchar2(10),id number(10),name varchar2(10));
表已创建。
create or replace trigger tirgger_t
after insert on t for each row declare -- local variables here begin insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),‘insert‘, :new.id,:new.name);(这里记录的是插入后的值,如果换成:old.id,则此列值为空
end tirgger_t; 此时我们插入数据验证:
SQL> insert into t values(0,‘os‘); 已创建 1 行。 SQL> set linesize 1000; SQL> set pagesize 1000; SQL> select * from t_trigger;
USERNAME IP TIME TER MINAL EVENT ID NAME -------------------- ---------------------------------------- -------------- --- ------------------------------------- -------------------- ---------- ---------- ---------- HR 170.12.15.20 19-4月 -15 PC2 01409141201 insert 0 os
注意::new,:old不能用在表级触发器中
在pl/sql中,提供了inseting,updating,deleting谓词用作流程语句中。
上述触发器如果写成一下形式:
create or replace trigger tirgger_t after insert on t -- for each row 注释此行 declare -- local variables here begin insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),‘insert‘, null,null); end tirgger_t; 则只记录插入的第一行,for ecah row 失效。 System触发器:(不能基于表或视图)
ddl触发器:
create or replace trigger t_tirgger_ddl after ddl on hr.schema =>对于ddl触发器,可以直接写ddl,系统会识别何操作 declare -- local variables here begin insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent, null,null); end t_tirgger_ddl;
for each row 不能用于对象触发器 对于schema,很多初学者很困惑,不知道这个是什么概念,这个逻辑概念很重要,指用户具有所有对象的集合。
SQL> alter table t add address varchar2(20); 表已更改。 SQL> select * from t_trigger; USERNAME IP TIME TERMINAL EVENT ID NAME -------------------- -------------------- -------------------- ----------------- --- -------------------- ---------- -------------------- HR170.12.15.20 19-4月 -15 PC201409141201ALTERdb触发器:当STARTUP、SHUTDOWN、LOGON、LOGOFF数据库时就会触发DB事件触发器,这种触发器可以用来监控数据库什么时候关闭或打开,或者用户的LOGON/LOGOFF数据库情况(shutdown类型要用关键字before,startup用after)
create or replace trigger t_tirgger_db after logon on hr.schema declare -- local variables here begin insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent, null,null); end t_tirgger_db; 重新连接:
SQL> select * from t_trigger; USERNAME IP TIME -------------------- ---------------------------------------- -------------- TERMINAL EVENT ID ---------------------------------------- -------------------- ---------- NAME -------------------- HR170.12.15.20LOGON 19-4月 -15 PC201409141201同理也可以创建:create or replace trigger t_tirgger_db after logoff on hr.schema declare -- local variables here begin insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent, null,null); end t_tirgger_db;instead-of触发器:
SQL> create view t_view as select name,id from t; 视图已创建。 create or replace trigger t_tirgger_view instead of insert on t_view for each row declare -- local variables here begin insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent, :new.id,:new.name); end t_tirgger_view;SQL> insert into t_view values(‘0‘,0);已创建 1 行。SQL> select * from t_trigger; USERNAME IP TIME -------------------- ---------------------------------------- -------------- TERMINAL EVENT ID ---------------------------------------- -------------------- ---------- NAME -------------------- HRDROP TRIGGER trigger_name;当然你要有相关权限,在第三方工具中操作更加方便,如(pl/sql developer)170.12.15.200 0删除触发器比较简单:19-4月 -15 PC201409141201
标签:
原文地址:http://blog.csdn.net/bat_os/article/details/45131239