首页 > 代码库 > DML触发器

DML触发器

 

数据库触发器是特殊的存储程序。通常不直接调用它们,而是由数据库的事件触发。
触发器分类:
    >DML触发器
    >instead-of触发器
    >系统事件触发器,还可以是DDL
一. DML触发器
在数据库上执行insert,update,delete时,DML触发器会被激活。
种类                 说明
语句 insert,update,delete    定义导致激活触发器的类型
激活时间 before,after         什么时候执行
级别 行级,语句级         行级:激活事件针每影响一行记录,触发一次



--
eg.1 create or replace trigger author_tring --触发器名 after update of first_name --激活时间 on authors --针对的表 for each row --语句级 when(OLD.first_name!=NEW.first_name) --限制 begin --动作(触发器主体) DBMS_OUTPUT.PUT_LINE( First Name ||:OLD.first_name ||has change to ||:NEW.first_name ); end; / --eg.2 --用category_stats表存储存books表的各类型category的图书数目和平均价格 create table category_stats( catageory_stats varchar(20), total_books number, average_price number ); --实现:当books表改变后,catageory_stats表的信息自动改变 create or replace trigger UpdateCategoryStats after insert or deleteor update on books --针对的表 declare --声明 cursor c_Statistics is select category, count(*) total_books, avg(price) average_price from books group by category --使用游标记录books表的一些聚合信息 begin delete from table category_stats; --删除原来的信息 for v_StatsRecord in c_Statistics loop --遍历游标,将信息插入到category_stats表 insert into category_stats(category_stats,total_books,average_price) vaules(v_StatsRecord.category,v_StatsRecord.total_books, v_StatsRecord.average_price); end loop; end UpdateCategoryStats;
1. DML触发器的激活顺序
>1.执行before 语句级触发器
>2.对受该语句影响的每一条记录
    .执行before行级触发器
    .执行语句本身
    .执行after行级触发器
>3.执行语句级触发器

create sequence trig_seq
    start with 1
    increment by 1;

create or replace package TrigPackage as
    v_Counter  number;
end TrigPackage;

create or replace trigger BooksBStatement    
    before update on books
begin
    TrigPackage.v_Counter:=0;   --语句级before触发器
    insert into temp_table(num_col,char_col)
    vaules(trig_seq.nextval,before statement:counter=||TrigPackage.v_Counter);
    TrigPackage.v_Counter:=TrigPackage.v_Counter+1;
end BooksBStatement
/

create or replace trigger BooksAStatement1   --语句级after触发器1
    after update on books
begin
    insert into temp_table(num_col,char_col)
    vaules(trig_seq.nextval,after statement:counter1=||TrigPackage.v_Counter);
    TrigPackage.v_Counter:=TrigPackage.v_Counter+1;
end BooksBStatement1
/

create or replace trigger BooksAStatement2  --语句级after触发器2(会先执行2)
    after update on books
begin
    insert into temp_table(num_col,char_col)
    vaules(trig_seq.nextval,after statement:counter2=||TrigPackage.v_Counter);
    TrigPackage.v_Counter:=TrigPackage.v_Counter+1;
end BooksBStatement2
/


create or replace trigger BooksBRows1     --行级before触发器1
    before update  on books
    for each row
begin
    insert into temp_table(num_col,char_col)
    vaules(trig_seq.nextval,before row:counter1=||TrigPackage.v_Counter);
    TrigPackage.v_Counter:=TrigPackage.v_Counter+1;
end BooksBRows1
/

create or replace trigger BooksBRows2     --行级before触发器2
    before update  on books
    for each row
begin
    insert into temp_table(num_col,char_col)
    vaules(trig_seq.nextval,before row:counter2=||TrigPackage.v_Counter);
    TrigPackage.v_Counter:=TrigPackage.v_Counter+1;
end BooksBRows2
/


create or replace trigger BooksARow    ----行级after触发器
    after update  on books
    for each row
begin
    insert into temp_table(num_col,char_col)
    vaules(trig_seq.nextval,after row:counter=||TrigPackage.v_Counter);
    TrigPackage.v_Counter:=TrigPackage.v_Counter+1;
end BooksBRows
/
--测试
--books表中category=Oracle Ebusiness有两条记录
update books
set category =Oracle
where category=Oracle Ebusiness;

select * from temp_table
order by num_col;
结果:
num_col    char_col
1      before statement:counter=0
2      before row2:counter=1
3      before row1:counter=2
4      after row:counter=3
5      before row2:counter=4
6      before row1:counter=5
7      after row:counter=6
8      after statement:counter2=7
9      after statement:counter1=8
>>可以看到结果和上面归纳的顺序是一样的