Oracle 触发器

  1. 触发器:是特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。 
  2. 1 能让触发器执行的操作事件
  3. (1)DML事件:如:insert、delete、update。
  4. (2)系统事件:如:关闭数据库shutdown、启动数据库startup、服务器出错servererror发生时。
  5. (3)用户事件:如注册连接logon或注销logoff。
  6. (4)DDL事件:如create、drop、alter发生时。
  7. 2 触发器功能:
  8. (1)审计:提供审计和日志记录。
  9. (2)实现复杂业务规则。
  10. (3)产生导出值。
  11. (4)远程数据复制。
  12. (5)可进行系统事件处理。
  13. (6)强制数据一致性
  14. 3 触发器类型
  15. (1)DML触发器:它是在执行insert、delete、update语句时被激发执行。根据触发器所依赖的表对象不同,可将DML
  16. 触发器进行分为行级row触发器和语句级statement触发器。
  17.    使用最多,它只能定义在表上。
  18. (2)替代触发器:是被激发用于代替执行DML语句,它可以定义在表上、视图上(主要用于对相关视图的更新)。
  19. (3)系统触发器:可在两种不同的事件(DDL和数据库)上激活。
  20. DDL事件包括:create alter drop语句,
  21. 数据库事件:服务器的启动或关闭、用户的登录或退出,以及服务器错误。系统触发器常用于数据库的管理和维护。
  22. 触发器定义通用格式:
  23.     create or replace trigger <trigger_name>
  24.     [before | after | instead of]<triggering_event>
  25.     [referencing<referencing_clause>]
  26.     [when<trigger_restriction>]
  27.     [for each row]
  28.     <trigger_body>;
  29. 其中:
  30. ◇<triggering_event>:指激发触发器的特定事件,它可是下列事件中的一个或多个,若多个事件则用or分离。
  31. delete <event_ref>;
  32. insert <event_ref>;
  33. update <event_ref>;
  34. update of column,column...<event_ref>;
  35. <ddl_statement>on[schema.]{table|view}
  36. <ddl_statement>on[database]|[schema.]schema};
  37. servererror;
  38. logon;
  39. logoff;
  40. startup;
  41. shutdown;
  42. ◇<event_ref>:为激发触发器执行的对象。包括表、视图和嵌套表列。
  43. on [schema.]<table_name>
  44. on [schema.]<view_name>
  45. on [nested table<nested_table_column>of][schema.][view_name]
  46. ◇<referencing_clause>为:
  47. referencing old [as] old [for each row]
  48. referencing new [asnew [for each row]
  49. referencing parent [as] parent [for each row]
  50. ◇<referencing>:为当前:new和:old或:parent指定一个不同名称,用于引用正处于修改状态下行中的数据。这样可
  51. 进行保存或比较新旧值记录的值。只能用于行触发器。
  52. ◇<trigger_body>:触发器主体。
  53. ◇when <trigger_resrtiction>:指在满足了条件<trigger_resrtiction>后,才触发。
  54. ◇<trigger_name>触发器名称。
  55. 4 DML触发器:
  56. 在实际应用中,DML触发器最为常用。DML语句格式:
  57.     create or replace trigger <trigger_name>
  58.     [before | after]<triggering_event>
  59.     [referencing<referencing_clause>]
  60.     [when<trigger_restriction>]
  61.     [for each row]
  62.     <trigger_body>;
  63. (1)触发时机
  64. 在DML触发器中,根据其触发时机不同,触发时可分为:before和after。因此可分为before触发器和after触发器。
  65. (2)行级触发器和语句触发器
  66. 当创建触发器的语句添加了子句for each row,则为行级触发器。否则为语句触发器(系统默认)。
  67. 行级触发器:是由触发语句所变更的每一行激发的,即每变更一行就触发一次。
  68. 语句级触发器:就是语句执行之前或之后触发一次。
  69. 5 DML行级触发器属性
  70.         不同事件中标识符:old和:new的对应值
  71. ------------------------------------------------------------------------
  72.   触发事件      标识符:old     标识符:new 
  73. ------------------------------------------------------------------------
  74.   insert        无定义(所有字段为空) 该语句结束时将要插入的值
  75.   update        更新前,行的原始值。  该语句结束时将要更新的值
  76.   delete        删除前,行的原始值。  无定义(所有字段为空)
  77. -------------------------------------------------------------------------   
  78. DML触发器还有另外三个逻辑属性,也称为谓词表达式。用来确定是何种DML操作语句触发了触发器的执行。
  79.  ----------------------------------------------------------------------------------------
  80. ┆       ┆               谓词表达式(属性)           ┆   
  81. ┆执行的DML语句   ┆-----------------------------------------------------------------------
  82. ┆       ┆   inserting   ┆   updating    ┆   deleteing   ┆
  83. -----------------------------------------------------------------------------------------
  84. ┆   insert  ┆   true        ┆   false       ┆   false       ┆   
  85. ┆       ┆-----------------------------------------------------------------------
  86. ┆   update  ┆   false       ┆   true        ┆   false       ┆
  87. ┆        ------------------------------------------------------------------------
  88. ┆   delete  ┆   false       ┆   false       ┆   true        ┆
  89.  ----------------------------------------------------------------------------------------
  90. ◇触发器谓词判断语句的类型
  91. create or replace trigger stuInfo_infor
  92.   before insert or delete or update on stuInfo  
  93.   for each row
  94. declare
  95. begin
  96.    if inserting then
  97.       insert into stuMark values('s271820',:new.stuNo,0,0);
  98.    end if;
  99.    if deleting  then
  100.       delete from stuMark where stuNo=:old.stuNo;
  101.    end if;   
  102.    if updating then
  103.       update stuMark set writtenExam=100,labExam=100 where stuNo=:old.stuNo;
  104.    end if;
  105. end stuMark_infor;
  106. ◇利用referencing子句来引用触发器语句体中的数据
  107. 命令格式:
  108.   referencing [old as <custom_name_for_old>][new as <custom_name_for_new>]
  109. 其中,<custom_name_for_old>和<custom_name_for_new>是分别为:old和:new定义的名称。
  110. referencing子句为当前:new和:old指定一个不同名称,用于引用正处于修改状态下行中的数据。这样可以保存或比较旧记录的值。
  111. 该子句用在触发事件之后且when子句之前使用。只能用于行级触发器。
  112. ◇when条件子句的使用
  113. 只能用于行级触发器。表示满足条件时才触发。
  114. ◇利用:new产生导出数据
  115. 6替代触发器
  116. 替代触发器(instead of)触发器可用来操纵对视图的插入、修改和删除。当一个视图是根据几个表创建的时候,
  117. 替代触发器是非常有用的。一旦对视图进行了DML操作,则该操作会触发视图的替代触发器,改由触发器语句体
  118. 中的DML语句对构成该视图的基本表进行操作。其中视图中不能包括以下命令参数:
  119. 集合操作:如交、差、并。
  120. 聚集操作:如sum、avg等。
  121. group by、connect by 或start with以及distinct子句。
  122. before、after不能用于instead of操作。
  123. 替代触发器(instead of)语句格式:
  124.     create or replace trigger <trigger_name>
  125.     [instead of]<triggering_event>
  126.     [referencing<referencing_clause>]
  127.     [when<trigger_restriction>]
  128.     [for each row]
  129.     <trigger_body>;
  130. 建立视图:
  131. create or replace view stuInfo as select * from stuInfo;
  132. 建立触发器:
  133. 在进行更新时,检查stuName的新旧值,如果不同,则进行更新。
  134. create or replace trigger stuInfo_change
  135.   instead of update on v_stuinfo  
  136.   for each row
  137. declare
  138.   -- local variables here
  139. begin
  140.   if(:new.stuName<>:old.stuName) or (:old.stuName is null and :new.stuName is not null) then
  141.     update stuInfo set stuName=:new.stuName where stuNo=:new.stuNo;
  142.   end if;
  143. end stuInfo_change;
  144. update v_stuInfo set stuName='test' where stuNo='s25303';
  145. 7 系统触发器
  146. 根据事件类型系统触发器分为:
  147. 数据库触发器:数据库触发器的DDL事件包括:create alter drop事件。
  148. 模式触发器:服务器的启动或关闭以及服务器错误。
  149. 用户触发器:用户登录或退出。
  150. 系统触发器语法格式:
  151.     create or replace trigger [schema.] <trigger_name>
  152.     [before | after]<triggering_event>
  153.     [<ddl_event_list><database_event_list>]
  154.     on{database | [schema.]schema}
  155.     [when_clause]
  156.     <trigger_body>;
  157. 其中:
  158. [before | after]:为触发时机。
  159. <ddl_event_list>:是一个或多个DDL事件。
  160. <database_event_list>:是一个或多个数据库事件。若定义中使用了on database子句,则为
  161. 数据库级触发器,如果选用了on schema子句,则为模式触发器。
  162. (1)创建数据库登录触发器,触发时机为after.
  163. 创建系统信息表
  164. create table connection_audit(
  165.  login_date date,
  166.  username varchar2(30));
  167. create or replace trigger logon_audit
  168.   after logon on database  
  169. begin
  170.   insert into connection_audit(login_date,username ) values(sysdate,user);
  171. end logon_audit;
  172. (2)创建用于记录登录失败信息的触发器
  173. create or replace trigger logon_failures
  174.   after servererror on database  
  175. begin
  176.   if(is_servererror(1017)) then
  177.     insert into connection_audit(login_date,username ) values(sysdate,'ora-1017'); 
  178.   end if;
  179. end logon_failures;
  180. (2)数据库审计
  181. 数据库审计,可以使用startup触发器和shutdown触发器来记录数据库启动和关闭的时间,用户等信息。
  182. create table updown_log(
  183.  database_name varchar2(30),
  184.  event_name varchar2(20),
  185.  event_time date,
  186.  triggered_user varchar2(30));
  187. create or replace trigger log_startup_infor
  188.   after startup on  database
  189. begin
  190.   insert into updown_log(database_name,event_name,event_time,triggered_user)
  191.   values(sys.database_name,sys.sysevent,sysdate,sys.login_user);
  192. end log_startup_infor;
  193. create or replace trigger log_shutdown_infor
  194.   before shutdown on database  
  195. begin
  196.     insert into updown_log(database_name,event_name,event_time,triggered_user)
  197.     values(sys.database_name,sys.sysevent,sysdate,sys.login_user);
  198.     commit;
  199. end log_shutdown_infor;
  200. (3)模式或DDL事件触发器
  201. 审计模式修改的触发器,关键词是schema.
  202. create table alter_ddl_audit(
  203.  object_owner     varchar2(30),
  204.  object_name      varchar2(30),
  205.  object_type      varchar2(20),
  206.  object_by_user   varchar2(30),
  207.  alteration_time  date);
  208. create or replace trigger audit_schema_alter
  209.   after create or alter or drop on system.schema  
  210. begin
  211.   insert into alter_ddl_audit(object_owner,object_name,object_type,object_by_user,alteration_time)
  212.   values(sys.dictionary_obj_owner,sys.dictionary_obj_name,sys.dictionary_obj_type,sys.login_user,sysdate);
  213. end audit_schema_alter;
  214. 8 触发器的状态
  215. 触发器的状态包括无效(disable)与有效(enable)两种状态。
  216. alter trigger <trigger_name>[disable | enable]
  217. 9触发器应用
  218. (1)触发器实现字段列自增长
  219. create table stu(
  220.  stuID number(10),
  221.  stuName varchar2(20));
  222. create sequence autoId start with 1 increment by 1 cache 200;
  223. create or replace trigger getautoId
  224.   before insert on stu  
  225.   for each row
  226. declare
  227.   -- local variables here
  228. begin
  229.   select autoId.Nextval into :new.stuId from dual;
  230. end getautoId;
  231. insert into stu values(null,'s');
  232. insert into stu values(null,'s1');
  233. insert into stu values(null,'s2');
  234. insert into stu values(null,'s3');
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值