触发器的建立

触发器的建立create or replace trigger before_insert_update_delete
before insert or update or delete on T for each row
begin
    null;
end;
/
create or replace trigger before_insert_update_delete
after insert or update or delete on T for each row
begin
    null;
end;
/

触 发器(trigger)是个特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由个事件来触发,比如当对一个表进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到。

触发器可以查询其他表,而且可以包含复杂的 SQL 语句。它们主要用于强制服从复杂的业务规则或要求。例如,您可以根据客户当前的帐户状态,控制是否允许插入新订单。

触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。然而,强制引用完整性的最好方法是在相关表中定义主键和外键约束。如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。

最基本的触发器是针对表的Insert、Update、Delete这三种操作来的。触发器可以建立在表上,也可以建立在视图上。建立在表上的触发 器会在表内容发生改变时触发。建立在视图上的触发器会在视图内容改变时触发。注意,视图触发器仅会在明确对视图进行操作的SQL语句执行时才会触发,当基 本表的内容发生改变而引起视图内容变化时,不会触发视图触发器。

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

功能:
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,
);

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

原文地址:https://www.cnblogs.com/danghuijian/p/4400753.html