oracle之触发器(trigger)

来源:互联网 发布:网络包年维护服务 编辑:程序博客网 时间:2024/05/22 08:14

(一)触发器(trigger)

        触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动地隐式运行。并且,触发器不能接收参数。所以运行触发器就叫触发或点火(firing)。ORACLE事件指的是对数据库的表进行的INSERT、UPDATE及DELETE操作或对视图进行类似的操作。ORACLE将触发器的功能扩展到了触发ORACLE,如数据库的启动与关闭等。

        所以触发器常用来完成由数据库的完整性约束难以完成的复杂业务规则的约束,或用来监视对数据库的各种操作,实现审计的功能。

(二)触发器格式

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    // 表示建立在哪个表或视图上执行的哪种DML语句的前触发器或后触发器


[FOR EACH ROW ]  //表示为行触发器


[WHEN condition]   //只在行触发器中使用,可以省略


PL/SQL_BLOCK ;     //就是begin 执行语句; end;

格式说明:

     BEFORE 和AFTER指出触发器的触发时序分别为前触发和后触发方式。

       FOR EACH ROW选项说明触发器为行触发器。行触发每次都会激活触发器;

       语句触发器(省略for  each  row)将整个语句操作作为触发事件,整个语句执行完,激活一次触发器。

       INSTEAD OF 触发器(替换触发器)则只能为行触发器。

       WHEN 子句说明触发约束条件。Condition 为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用PL/SQL 函数。WHEN 子句指定的触发约束条件只能用在BEFORE 和AFTER 行触发器中,不能用在INSTEAD OF 行触发器和其它类型的触发器中。

       当一个基表被修改( INSERT, UPDATE, DELETE)时要执行的存储过程,执行时根据其所依附的基表改动而自动触发,因此与应用程序无关,用数据库触发器可以保证数据的一致性和完整性。(简而言之:关联表也会执行触发器的操作

       触发器的PL/SQL块中应用相关名称(就是触发器执行前后的字段的值)时,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。

:NEW 修饰符访问操作完成后列的值

:OLD 修饰符访问操作完成前列的值

(三)实例应用

建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。

CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2


CREATE OR REPLACE TRIGGER tr_del_emp 
   BEFORE 
DELETE --指定触发时机为删除操作前触发,多个操作用or来连接
   ON scott.emp 
   
FOR EACH ROW   --说明创建的是行级触发器 

--以上是建立触发器的语句
BEGIN
   
--将修改前数据插入到日志记录表 del_emp ,以供监督使用。
   INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate )
       
VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :old.comm, :old.hiredate );  //引用触发器执行之前的值,必须加:(冒号)
END;
DELETE emp WHERE empno=7788;
DROP TABLE emp_his;
DROP TRIGGER del_emp;


(四)trigger相关操作(user_trigger,all_trigger,dba_trigger)

--查看所有触发器
select * from user_triggers;
--禁用触发器
alert trigger tri_log_uname(触发器名字) disable;
--激活触发器
alert trigger tri_log_uname(触发器名字) enble;
--重新编译
alert trigger tri_log_uname complie;
--禁用某个表上的触发器
alert table <table_name> diable all triggers;

删除触发器

drop  trigger  触发器名;


(五)触发器实例

create table emp2_log
(
uname varchar2(20),
action varchar(10),
atime date
)
-----------
create or replace trigger trig
  after insert or update or delete on emp2    //多个操作用or来连接
begin
  if inserting then
     insert into emp2_log values (USER, 'insert', sysdate);
  elsif updating then
     insert into emp2_log values (USER, 'update', sysdate);
  elsif deleting then
     insert into emp2_log values (USER, 'delete', sysdate);
  end if;
end;


----------
update emp2 set sal = sal * 2 where deptno = 30;
--------
create or replace trigger trig
  after insert or update or delete on emp2 for each row
begin
  if inserting then
     insert into emp2_log values (USER, 'insert', sysdate);
  elsif updating then
     insert into emp2_log values (USER, 'update', sysdate);
  elsif deleting then
     insert into emp2_log values (USER, 'delete', sysdate);
  end if;
end;
-------------
--不提倡使用
create or replace trigger trig
 after update on dept for each row
begin
 update emp2 set deptno = :NEW.deptno where deptno = :OLD.deptno;
end;


可以参考文档:http://blog.csdn.net/indexman/article/details/8023740/