1. 触发器类似过程和函数,都保存在数据库中。
2. 触发器和过程不同的是:过程是由用户或应用程序显式调用的,而触发器是不能被直接调用。
3. 创建触发器语法:
create [or replace] trigger trigger_name
[before | after | instead of]
trigger_event
on table_name
[for each row[when tigger_condition]]
begin
trigger_body
end trigger_name;
注:instead of指定触发器为替代触发器。
for each row指定触发器为行级触发器,表示该触发器对影响到的每一行数据都触发执行一次;如果未指定该条件,则表示创建语句级触发器,这时无论影响到多少行,触发器都只会执行一次。
最好不要用alter语句触发器进行安全检查。可能会导致数据进行不必要的回退。
4. 触发器分类:
行级触发器;
语句触发器;
instead of触发器;
系统事件触发器;
用户事件触发器;
5. 语句触发器:
(1)create table emp_log
who varchar2(20),
when date);
(2)create or replace trigger emp_op
before insert or update or delete
on emp
begin
insert into emp_log(who,when)
values(user,sysdate);
end emp_op;
/
(3)更新emp表
update emp set sal=sal*1.1;
(4)查询emp_op表,看结果。
select * from emp_op;
(5)修改emp_log表,为其添加action列。
alter table emp_log
add (action varchar2(30));
(6)修改触发器:
create or replace trigger emp_op
before insert or update or delete
on emp
declare
var_action varchar2(30);
begin
if inserting then
var_action :='INSERT';
elsif updating then
var_action :='UPDATE';
elsif deleting then
var_action :='DELETE';
end if ;
insert into emp_log(who,when,action)
values(user,sysdate,var_action);
end emp_op;
/
(7)测试结果:
update emp set id=id*3;
select * from emp_log;
6. 行级触发器:
行级触发器一个重要特点,创建before行级触发器时,可以在触发器中引用受到影响的行值,甚至可以在触发器中设置它们。
下面的例子中,在表上创建一个行级触发器,并使用一种数据库对象(序列)生成主键值(这时常见的for each row)触发器的用途。
(1)创建一个测试表foo,以及同时使用的序列,序列的作用是自动生成一组排序数。
create table foo(sid number,sname varchar2(20));
create sequence seq_foo;
(2)创建生成主键的行级触发器
create or replace trigger foo_trigger
before insert or update of sid
on foo
for each row
begin
if inserting then
select seq_foo.nextval
into:new.sid
from dual;
else
raise_application_error (-20020,'不允许更新ID值!');
end if;
end;
/
(3)向表foo添加两行数据,以测试触发器是否能够成功运行
insert into foo(sid,sname) values(1,'xiaolili');
insert into foo(sname) values('xiaoli');
(4)查询验证
select * from foo;
SID SNAME
---------- -----
1 xiaolili
2 xiaoli
以后插入的行,sid都是递增的,即sid列都会使用SEQ_FOO.NEXTVAL的值。
前映像的相关性表示符:OLD
后映像的相关性标示符:NEW
注:在insert触发器中,由于不存储先前的数据,所以不能使用前映像:OLD,只能使用后映像:NEW。
在delete触发器中,只能使用:OLD。
在update触发器中,同时同时具有各个列的前映像值:NEW和后映像:OLD。
阅读(1013) | 评论(0) | 转发(0) |