触发器
是特定事件出现的时候自动执行的代码块类似于存储过程但是用户不能直接调用他们
功能
允许/限制对表的修改
自动生成派生列比如自增字段
强制数据一致性
提供审计和日志记录
防止无效的事务处理
启用复杂的业务逻辑
开始
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_valuedepartment_id<> )
:mission_pct :=;
触发器的组成部分
触发器名称
触发语句
触发器限制
触发操作
触发器名称
create trigger biufer_employees_department_id
命名习惯
biufer(before insert update for each row)
employees 表名
department_id 列名
触发语句
表或视图上的DML语句
数据库关闭或启动startup shutdown 等等
before insert or update
of department_id
on employees
referencing old as old_value
new as new_value
for each row
说明
无论是否规定了department_id 对employees表进行insert的时候
对employees表的department_id列进行update的时候
触发器限制
when (new_valuedepartment_id<> )
限制不是必须的此例表示如果列department_id不等于的时候触发器就会执行
其中的new_value是代表更新之后的值
触发操作
是触发器的主体
:mission_pct :=;
end;
主体很简单就是将更新后的commission_pct列置为
insert into employees(employee_id
last_namefirst_namehire_datejob_idemaildepartment_idsalarycommission_pct )
values( ChenDonny sysdate );
select commission_pct from employees where employee_id=;
触发器不会通知用户便改变了用户的输入值
触发器类型
语句触发器
行触发器
INSTEAD OF 触发器
系统条件触发器
用户事件触发器
语句触发器
是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器能够与INSERTUPDATEDELETE或者组合上进行关联但是无论使用什么样的组合各个语句触发器都只会针对指定语句激活一次比如无论update多少行也只会调用一次update语句触发器
例子
需要对在表上进行DML操作的用户进行安全检查看是否具有合适的特权
Create table foo(a number);
Create trigger biud_foo
Before insert or update or delete
On foo
If user not in (DONNY) then
Raise_application_error( You dont have access to modify this table);
End if;
即使SYSSYSTEM用户也不能修改foo表
[试验]
对修改表的时间人物进行日志记录
建立试验表
create table employees_copy as select *from hremployees
建立日志表
create table employees_log(
who varchar()
when date);
在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(
Whowhen)
Values( user sysdate);
End;
/
update employees_copy set salary= salary*;
select *from employess_log;
确定是哪个语句起作用?
即是INSERT/UPDATE/DELETE中的哪一个触发了触发器?
可以在触发器中使用INSERTING / UPDATING / DELETING 条件谓词作判断
if inserting then
elsif updating then
elsif deleting then
end if;
if updating(COL) or updating(COL) then
end if;
[试验]
修改日志表
alter table employees_log
add (action varchar());
修改触发器以便记录语句类型
Create or replace trigger biud_employee_copy
Before insert or update or delete
On employees_copy
Declare
L_action employees_logaction%type;
Begin
if inserting then
l_action:=Insert;
elsif updating then
l_action:=Update;
elsif deleting then
l_action:=Delete;
else
raise_application_error(You should never ever get this error);
Insert into employees_log(
Whoactionwhen)
Values( user l_actionsysdate);
End;
/
insert into employees_copy( employee_id last_name email hire_date job_id)
values(ChenDonny@hotmailsysdate);
select *from employees_log