触发器基础知识

触发器

是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。

功能:


1、 允许/限制对表的修改


2、 自动生成派生列,比如自增字段


3、 强制数据一致性


4、 提供审计和日志记录


5、 防止无效的事务处理


6、 启用复杂的业务逻辑

开始
create trigger biufer_employees_department_id
       before insert or update
             of department_id
             on employees
       referencing old as old_value
                   new as new_value
       for each row
       when (new_value.department_id<>80 )
begin
       :new_value.commission_pct :=0;
end;
/

 


触发器的组成部分:


1、 触发器名称


2、 触发语句


3、 触发器限制


4、 触发操作

 


1、 触发器名称


create trigger biufer_employees_department_id


命名习惯:


biufer(before insert update for each row)


employees 表名


department_id 列名

 


2、 触发语句


比如:


表或视图上的DML语句


DDL语句


数据库关闭或启动,startup shutdown 等等


before insert or update


              of department_id


              on employees


       referencing old as old_value


                       new as new_value


       for each row
说明:


1、 无论是否规定了department_id ,对employees表进行insert的时候


2、 对employees表的department_id列进行update的时候


3、 触发器限制


when (new_value.department_id<>80 )

 


限制不是必须的。此例表示如果列department_id不等于80的时候,触发器就会执行。


其中的new_value是代表跟新之后的值。

 


4、 触发操作


是触发器的主体


begin


       :new_value.commission_pct :=0;


end;

 


主体很简单,就是将更新后的commission_pct列置为0


触发:


insert into employees(employee_id,


last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct )


values( 12345,’Chen’,’Donny’, sysdate, 12, ‘donny@hotmail.com’,60,10000,.25);

select commission_pct from employees where employee_id=12345;

触发器不会通知用户,便改变了用户的输入值。


触发器类型:


1、 语句触发器


2、 行触发器


3、 INSTEAD OF 触发器


4、 系统条件触发器


5、 用户事件触发器


1、 语句触发器


是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器。能够与INSERT、UPDATE、DELETE或者组合上进行关联。但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次。比如,无论update多少行,也只会调用一次update语句触发器。

 


例子:


需要对在表上进行DML操作的用户进行安全检查,看是否具有合适的特权。


Create table foo(a number);

Create trigger biud_foo
       Before insert or update or delete On foo

begin
       If user not in (‘DONNY’) then
             Raise_application_error(-20001, ‘You don’t have access to modify this table.’);
      End if;
End;


/
即使SYS,SYSTEM用户也不能修改foo表

[试验]


对修改表的时间、人物进行日志记录。


1、 建立试验表


create table employees_copy as select *from hr.employees

2、 建立日志表


create table employees_log(who varchar2(30),when date);

3、 在employees_copy表上建立语句触发器,在触发器中填充employees_log 表。


Create or replace trigger biud_employee_copy
            Before insert or update or delete On employees_copy
       Begin
              Insert into employees_log(Who,when) Values( user, sysdate);
       End;
       /

4、 测试

update employees_copy set salary= salary*1.1;
select *from employess_log;

5、 确定是哪个语句起作用?


即是INSERT/UPDATE/DELETE中的哪一个触发了触发器?


可以在触发器中使用INSERTING / UPDATING / DELETING 条件谓词,作判断:


begin
       if inserting then
              -----
        elsif updating then
              -----
        elsif deleting then
              ------
        end if;
end;

if updating(‘COL1’) or updating(‘COL2’) then
       ------
end if;

[试验]


1、 修改日志表


alter table employees_log

       add (action varchar2(20));


2、 修改触发器,以便记录语句类型。


Create or replace trigger biud_employee_copy
              Before insert or update or delete On employees_copy
       Declare
              L_action employees_log.action%type;
       Begin
        if inserting then
               l_action:=’Insert’;
        elsif updating then
               l_action:=’Update’;
        elsif deleting then
               l_action:=’Delete’;
        else
              raise_application_error(-20001,’You should never ever get this error.’);
              Insert into employees_log(Who,action,when) Values( user, l_action,sysdate);
       End;
       /
3、 测试
      insert into employees_copy( employee_id, last_name, email, hire_date, job_id)
      values(12345,’Chen’,’Donny@hotmail’,sysdate,12);
select *from employees_log
update employees_copy set salary=50000 where employee_id = 12345;

2、 行触发器

是指为受到影响的各个行激活的触发器,定义与语句触发器类似,有以下两个例外:

1、 定义语句中包含FOR EACH ROW子句

2、 在BEFORE……FOR EACH ROW触发器中,用户可以引用受到影响的行值。

比如:
定义:

create trigger biufer_employees_department_id
       before insert or update of department_id on employees_copy
       referencing old as old_value new as new_value
       for each row
       when (new_value.department_id<>80 )
begin
       :new_value.commission_pct :=0;
end;
/
Referencing 子句:


执行DML语句之前的值的默认名称是 :old ,之后的值是 :new


insert 操作只有:new


delete 操作只有 :old


update 操作两者都有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值