ORACLE 触发器

触发器可以看作一种“特殊”的存储过程,它定义了一些与数据库相关事件(如:INSERT 、UPDATE、CREATE等事件)发生时应执行的“功能代码块”,通常用于管理复杂的完整性约束,或监控对表的修改,或通知其他程序,甚至可以实现对数据的审计功能。

触发器概述

1、在触发器中有一个触发事件,触发器是通过这个“触发事件”来执行的(而存储过程的调用或执行是由用户或应用程序进行的)。能够引起触发器运行的操作被称为“触发事件”,如执行DML语句(使用INSERT、UPDATE、DELETE语句对表或视图执行数据处理操作);执行DDL语句(CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象);引发数据库系统事件(如系统启动或退出、产生异常错误等);引发用户事件(如登录或退出数据库操作)。语法格式如下:

2、关键字:

trigger:表示创建触发器的关键字,就如同创建存储过程的关键字“produce”一样

      before | after | instead of:表示“出发时机”的关键字。before表示在执行DML等操作之前触发,这种方式能够防止某些错误操作发生而便于回滚或是实现某些业务规则;after表示在DML等操作发生之后发生,这种方式便于记录该操作或做某些事后处理信息;instead of表示触发器为替代触发器。

      on:表示操作的数据表、视图、用户模式和数据库等,对它们执行某种数据操作(比如对表执行INSERT、ALTER、DROP等操作),将引起触发器的运行。

      for each row:指定触发器为行级触发器,当DML语句对每一行数据进行操作时都会引起该触发器的运行。如果未指定该条件,则表示创建语句级触发器,这时无论数据操作影响多少行,触发器都只会执行一次。

语法中的参数及说明:

      tri_name:触发器的名称,如果数据库中已经存在了此名称,则可以指定“or replace”关键字,这样新的触发器将覆盖掉原来的触发器。

      tri_event:触发事件,比如常用的INSERT、UPDATE、DELETE、CREATE、ALTER、DROP等。

      table_name | view_name | user_name |db_name:分别表示操作的数据表、视图、用户模式和数据库,对它们的某些操作将引起触发器的运行。

      tri_condition:表示触发器条件表达式,只有当该表达式的值为true时,遇到触发事件才会自动执行触发器,使其执行触发操作,否则即便是遇到触发事件也不会执行触发器。

      plsql_sentences:PL/SQL语句,它是触发器功能实现的主体。

Oracle所支持的触发器分为以下5类:

      行级触发器:当DML语句对每一行数据进行操作时都会引起该触发器的运行。

      语句级触发器:无论DML语句影响多少行数据,其所引起的触发器仅执行一次。

      替换触发器:该触发器是定义在视图上的,而不是定义在表上,它是用来替换所使用实际语句的触发器。

      用户事件触发器:是指与DDL操作或用户登录、退出数据库等事件相关的触发器。如,用户登录到数据库或使用ALTER语句修改表结构等。

      系统事件触发器:是指在Oracle数据库系统的事件中进行触发的触发器,如Oracle实例的启动与关闭。

语句级触发器

语句级触发器,是针对一条DML语句而引起的触发器执行。在语句级触发器中,不使用for each row子句,也就是说无论数据操作影响多少行,触发器都只会执行一次。

(1)本实例要实现的主要功能是使用触发器在SCOTT模式下针对表dept表的各种操作进行监控,为此首先需要创建一个日志表dept_log它用于存储对dept表的各种数据操作信息,比如操作种类(如插入、修改、删除操作)、操作时间等,下面创建一个日志信息表

例如:在SCOTT模式下创建dept_log数据表,并在其中定义两个字段,分别用来存储操作种类信息和操作日期,

(2)创建一个关于emp表的语句级触发器,将用户对dept表的操作信息保存到dept_log表中

例如:创建一个触发器tri_dept,该触发器在insert、update和delete事件下都可以被触发,并且操作的数据对象是dept表,要求在触发器执行时输出对dept表所做的具体操作

行级触发器

行级触发器会针对DML操作所影响的每一行数据都执行一次触发器。创建这种触发器时,必须在语法中使用for each row。使用行级触发器的一个典型应用就是给数据表生成主键值

(1)为了使用行级触发器生成数据表中的主键值,首先需要创建一个带有主键列的数据表

例如:在SCOTT模式下,创建一个用于存储商品种类的数据表,其中包括商品序号列和商品列名称

(2)为了给goods表的id列生成不能重复的有序值,需要创建一个序列

如:使用create sequence 语句创建一个序列,命名为seq_id

(3)在创建了数据表goods和序列seq_id之后,准备工作完成,接着来创建一个触发器,用于为goods表的id列赋值。例如:创建一个行级触发器,该触发器在数据表goods插入数据时被触发,并且在该触发器的主体中实现设置goods表的id列的值

(4)在触发器创建完毕后,用户可以通过向goods表中插入数据来验证触发器是否被执行,同时也能够验证该行级触发器是否能够使用序列为表的主键赋值

例如:向goods表中插入两条记录,其中一条记录不指定id列的值,由序列seq_id来产生;另一条记录指定id的值;

替换触发器

替换触发器-instead of触发器,它的“触发时机”关键字是instead of,而不是before或after。与其他类型触发器不同是,替换触发器定义在视图(一种数据库对象),而不是定义在表上。由于视图是由多的基表连接组成的逻辑结构,所以一般不允许用户进行DML操作(如INSERT、UPDATE、DELETE等操作),这样当用户为视图编写“替换触发器”后,用户对视图的DML操作实际上就变成了执行触发器中的PL/SQL语句块,这样就可以通过在“替换触发器”中编写适当的代码对构成视图的各个基表进行操作。

(1)为了创建并使用替换触发器,首先需要创建一个视图

例如:在SYSTEM模式下,给SCOTT用户授予“create view”(创建视图)权限,然后在SCOTT模式下创建一个检索雇员信息的视图,该视图包括dept表(部门表)和emp表(雇员表)

(2)接下来编写一个关于view_emp_dept视图在insert事件中的触发器

例如:创建一个关于view_emp_dept视图的替换触发器,在该触发器的主体中实现向emp表和dept表中插入两行关联的数据

(3)当触发器tri_insert_view成功创建之后,在向view_emp_dept视图中插入数据时,Oracle就不会产生错误信息,而是引起触发器“tri_insert_view”的运行,从而实现向emp表和dept表中插入两行数据。

例如:首相向视图view_emp_dept插入一条记录,然后在该视图中检索插入的记录行E

用户事件触发器

用户事件触发器是因进行DDL操作或用户登录、退出等操作而引起运行的触发器,,引起该类型触发器运行的常见用户事件包括:CREATE、ALTER、DROP、ANALYZE、COMMENT、GRANT、REVOKE、RENAME、TRUNCATE、SUSPEND、LOGON和LOGOFF等。

(1)首先创建一个日志信息表,用于保存DDL操作的信息

例如:使用create table语句创建一个日志信息表,该表保存的日志信息包括数据对象、数据对象类型、操作行为、操作用户和操作日期等

(2)创建一个用户触发器,用于将当前模式下的DDL操作信息保存到上面所创建的ddl_oper_log日志信息表中。关于scott用户的DDL操作(这里包括CREATE、ALTER和DROP)创建一个触发器,然后将DDL操作的相关信息插入到ddl_oper_log日志表中

(3)在创建完毕触发器之后,为了引起触发器的执行,就要在scott模式下进行DDL操作

例如:在SCOTT模式下,创建一个数据表和一个视图,然后删除视图和修改数据表,最后使用select语句查看ddl_oper_log日志表中的DDL操作信息


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值