oracle pl/sql 中的触发器

oracle 11g 将触发器分为5种:

1.DDL触发器:当在数据库中创建、修改、重命名、删除对象时触发。

2.DML或行级别触发器:当在表中插入、更新 或 删除数据时触发;可用于在值被改变前(before)进行审核、检查、保存、和替代。

3.复合触发器: 既是语句级又是行级触发器。在需要同时使用语句级触发器和行级触发器时可以使用复合触发器。

4.insteadof 触发器:用于停止DML语句的执行并重定向DML语句,即视图触发器。

5.系统或数据库事件触发器:用于跟踪系统事件。

注意:触发器中不能做dcl操作(savepoint、commit、rollback),也不能在所调用的函数和过程中执行 dcl操作。

   触发器声明自治则可以包含dcl语句,语法:pragma autonomous_transaction;

   变异表是一个正在改变的表,当表在改变时不能对表进行查询或修改操作,否则提示:ORA-04091。

        触发器主体不能大于32760个字节(因为触发器主体存贮在long数据类型的列中),所以建议将功能写在过程或函数中。

        触发器中不能使用long\long row类型的变量,long\long row类型的列不能使用:new和:old伪记录。

   语句级(表级)触发器不能使用:new和:old伪记录,不能用于收集事务的详细信息,否则提示:ORA-04082。

        行级触发器中,when子句使用new和old伪记录,触发器可以修改:new和:old伪记录的值。

    复合触发器不支持when子句,不支持自治,不支持exception块,不支持goto,不支持:new和:old伪记录(除行级语句块外)。

    只有dml语句能触发复合触发器,且必须有修改的行,触发器必须实现before statement 和after statement 块  才能触发。

举例:

1.用包头来定义数据结构

CREATE OR REPLACE Package Pkg_BldroomData_duBuildarea
As
 type p_buildids is table of bldroom.buildid%type index by binary_integer;
 v_buildids p_buildids;
 v_NumEntries binary_integer := 0;
End Pkg_BldroomData_duBuildarea;
/
show err;

2.行级触发器
Create Or Replace Trigger Tri_Bldroom_Biud_duBuildarea
 After Insert Or Delete Or Update Of buildid,resopertype,buildarea,designusage On bldroom for each row
Declare
Begin
 --[记录数据]--
 if inserting then
  Pkg_BldroomData_duBuildarea.v_NumEntries := Pkg_BldroomData_duBuildarea.v_NumEntries + 1;
  Pkg_BldroomData_duBuildarea.v_buildids(Pkg_BldroomData_duBuildarea.v_NumEntries) := :new.buildid;
 elsif deleting then
  Pkg_BldroomData_duBuildarea.v_NumEntries := Pkg_BldroomData_duBuildarea.v_NumEntries + 1;
  Pkg_BldroomData_duBuildarea.v_buildids(Pkg_BldroomData_duBuildarea.v_NumEntries) := :old.buildid;
 elsif updating then
  if :new.resopertype<>:old.resopertype or :new.buildarea<>:old.buildarea or :new.designusage<>:old.designusage then
   Pkg_BldroomData_duBuildarea.v_NumEntries := Pkg_BldroomData_duBuildarea.v_NumEntries + 1;
   Pkg_BldroomData_duBuildarea.v_buildids(Pkg_BldroomData_duBuildarea.v_NumEntries) := :old.buildid;   
  end if;
  if :new.buildid<>:old.buildid then
   Pkg_BldroomData_duBuildarea.v_NumEntries := Pkg_BldroomData_duBuildarea.v_NumEntries + 1;
   Pkg_BldroomData_duBuildarea.v_buildids(Pkg_BldroomData_duBuildarea.v_NumEntries) := :old.buildid; 
   Pkg_BldroomData_duBuildarea.v_NumEntries := Pkg_BldroomData_duBuildarea.v_NumEntries + 1;
   Pkg_BldroomData_duBuildarea.v_buildids(Pkg_BldroomData_duBuildarea.v_NumEntries) := :new.buildid;   
  end if;
 end if;
End Tri_Bldroom_Biud_duBuildarea;
/
show err;

3.语句级触发器
Create Or Replace Trigger Tri_Bldroom_AllAiu_duBuildArea
 After Insert Or Delete Or Update Of buildid,resopertype,buildarea,designusage On bldroom
Declare
 l_buildid  bldroom.buildid%type;
Begin
 for v_LoopIndex in  1..Pkg_BldroomData_duBuildarea.v_NumEntries loop
  --[获取变量]--
  l_buildid := Pkg_BldroomData_duBuildarea.v_buildids(v_LoopIndex);
  --[汇总面积]--
  proc_blddesignusagearea(l_buildid);
  end loop;
 Pkg_BldroomData_duBuildarea.v_NumEntries := 0;
End Tri_Bldroom_AllAiu_duBuildArea;
/
show err;

原文地址:https://www.cnblogs.com/BradMiller/p/1743997.html