触发器 trigger

触发器是被指定关联到一个表的数据对象,它不须要调用,当对一个表的特别事件出现时,它就被激活。触发器的代码也是由SQL语句组成的,所以用在存储过程当中的语句也能够用再触发器的定义中。触发器是一类特殊的存储过程,与表的关系密切,用于保护表中的数据,当有操做影响到触发器保护的数据时,触发器将自动执行。数据库

(1)DML触发器:当数据库中发生数据操做语句(DML)事件时调用DML触发器。DML事件包括用表或视图的 insert语句,update语句和delect语句,所以DML触发器可分为3种。服务器

(2)代替触发器:因为oracle中不能直接对两个以上的表创建的视图进行操做,因此给出了代替触发器。它是oracle专门为进行视图操做的一种处理方式。oracle

3)系统触发器:系统触发器也由相应的事件触发,但它的激活通常基于对数据库系统所进行得操做,如数据定义语句(DDL),启动或关闭触发器,链接或断开,服务器错误等系统事件。函数

命令建立触发器:spa

--语法格式
create  or replace trigger 触发器的名称
before  /after/instead of
insert/update/delete  
on  for each row

说明:日志

触发器名称:触发器的名字与过程名和包的名字不同,它有单独的名字空间,所以触发器名能够和表名或过程名同名,但在同一个方案中的触发器名不能相同。code

after:触发器在指定操纵都成功执行后触发,如after insert 表示在向表中插入数据后激活触发器对象

before:触发器在指定操做执行前触发,如before insert 表示在向表中插入数据前激活触发器blog

instead of: 指定建立代替触发器,触发器指定的事件不执行,而执行触发器自己的操做。事件

delete,insert,update:指定一个或多个触发器,多个触发器事件之间用 or 链接

of:指定在某列上update触发器,若是为多列,则须要使用逗号分隔。

for each row:在触发器定义中,若是未使用for each row 子句则表示触发器为语句触发器,触发器在激活后只执行一次,而无论这一操做将影响多行。

 

建立触发器有如下限制:

(1) 代码大小。触发器代码大小必须小于32K。

(2) 触发器中有效语句能够包括DML语句,但不能包括DDL语句。ROLLBACK、COMMIT、SAVEPOINT也不能使用。可是,对于系统触发器(system trigger)可使用CREATE、ALTER、DROP TABLE和ALTER…COMPILE语句。

(3) LONG、LONG RAW和LOB的限制:

     ① 不能插入数据到LONG或LONG RAW;

     ② 来自LONG或LONG RAW的数据能够转换成字符型(如char、varchar2),可是不能超过32K;

     ③ 使用LONG或LONG RAW不能声明变量;

     ④ 在LONG或LONG RAW列中不能使用:NEW和:PARENT;

     ⑤ 在LOB中的:NEW变量不能修改。

(4) 引用包变量的限制。若是UPDATE或DELETE语句检测到当前的UPDATE冲突,则Oracle执行ROLLBACK到SAVEPOINT上并从新启动更新,这样可能须要屡次才能成功。

 

建立DML触发器:

--假设数据库中增长一新表school_students_old,表结构和表school_students相同,用来存放从school_students表
--中删除的记录。建立一个触发器,当school_students表被删除一行,把删除的记录写到日志表school_students_old中。
create table school_students_old2 //建立新表 ( STU_ID NVARCHAR2(
20) NOT NULL, STU_NAME NVARCHAR2(20) NOT NULL , STU_SEX NVARCHAR2(20) , STU_CREDITS NUMBER(2) , STU_BIRTHDAY DATE , STU_CLASS NVARCHAR2(20) ); select * from school_students_old2; create or replace trigger delete_stu //建立触发器 before delete on school_students for each row begin insert into school_students_old2 (STU_ID,STU_NAME,STU_SEX,STU_CREDITS,STU_BIRTHDAY,STU_CLASS) values (:old.STU_ID,:old.STU_NAME,:old.STU_SEX,:old.STU_CREDITS,:old.STU_BIRTHDAY,:old.STU_CLASS); end delete_stu; select * from school_students; select * from school_students_old;

 

建立代替触发器:

--在数据库中建立视图和触发器,以说明替代触发器。
create or replace view stu_avg
as
select
RESULT_STU,
avg(result_number) as stu_avg from
SCHOOL_RESULT
group by RESULT_STU;

select * from stu_avg where RESULT_STU='201632218031';

delete from stu_avg where RESULT_STU='201632218031';

create or replace trigger tr_stu_avg_delete
instead of delete on stu_avg for each row
begin
   delete from SCHOOL_RESULT 
   where result_stu=:old.result_stu;
end tr_stu_avg_delete;

 

建立系统触发器:

--建立当一个用户userA登陆时自动记录一些信息的触发器。
create table login_log
(
   v_user  varchar2(100),
   v_date  date
);

create or replace trigger tr_login_log
  after logon on schema
  declare 
   v_name VARCHAR2(20);
   begin
   select user into v_name from dual;
   insert into login_log values(v_name,sysdate);
   end tr_login_log;
  
  select * from login_log;
  

 

启用和禁用触发器:

在oracle中,与过程,函数,包不一样,触发器是能够被禁用和启用的,在有大量数据要导入数据库中时,为了不触发相应的触发器以节省处理时间,能够禁用触发器,使其暂时失效,触发器被禁用后任然存储在数据库中,只要从新启用既可使它从新工做。

oracle提供了alter trigger语句来禁用和启用触发器

--语法格式
alter trigger [<用户名方案名.>]<触发器>
    disable|enable;

其中:disable表示禁用触发器,enable表示启用触发器

 

触发器的删除:

--语法格式
drop trigger [<用户名方案名.>]<触发器>

也能够用界面删除触发器

相关文章
相关标签/搜索