Oracle中的触发器(trigger)用法及解读

 更新时间:2026年05月08日 14:55:20   作者:象在舞  
文章主要介绍了数据库触发器的概念、语法、注意事项以及基本要点,并提供了创建基于值的触发器的示例,触发器是在特定数据操作时自动执行的PL/SQL语句序列,主要用于保证数据一致性和完整性

1、触发器的定义

数据库触发器是一个与表相关联、存储PL/SQL语句的“东西”。

每当一个特定的数据操作语句(insert、update、delete)在指定的表上发出时,Oracle自动执行触发器中定义的语句序列。

例如:当员工信息插入后,自动输出“插入成功”的信息。

create or replace trigger empTrigger
 after insert on emp 
 for each row
declare
 -- 这里存放本地变量
begin
 dbms_output.put_line('插入成功!');
end empTrigger;

2、触发器的语法

上面是一个触发器简单的例子,我们接下来看下触发器的语法:

CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER }
{INSERT | DELETE | UPDATE [OF column [, column …]]}
[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]
ON [schema.]table_name | [schema.]view_name
[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]
[FOR EACH ROW ]
[WHEN condition]
PL/SQL_BLOCK | CALL procedure_name;

其中:

(1)BEFORE和AFTER指出触发器的触发时序分别为前触发和后触发方式,前触发是在执行触发事件之前触发当前所创建的触发器,后触发是在执行触发事件之后触发当前所创建的触发器。

(2)FOR EACH ROW选项说明触发器为行触发器。行触发器和语句触发器的区别表现在:行触发器要求当一个DML语句操走影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。当省略FOR EACH ROW 选项时,BEFORE和AFTER触发器为语句触发器,而INSTEAD OF触发器则只能为行触发器。

(3)REFERENCING子句说明相关名称,在行触发器的PL/SQL块和WHEN子句中可以使用相关名称参照当前的新、旧列值,默认的相关名称分别为OLD和NEW。触发器的PL/SQL块中应用相关名称时,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。

(4)WHEN子句说明触发约束条件。Condition为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用PL/SQL函数。WHEN 子句指定的触发约束条件只能用在BEFORE和AFTER行触发器中,不能用在INSTEAD OF行触发器和其它类型的触发器中。

(5)当一个基表被修改(INSERT、 UPDATE、DELETE)时要执行的存储过程,执行时根据其所依附的基表改动而自动触发,因此与应用程序无关,用数据库触发器可以保证数据的一致性和完整性。

行触发器要求当一个DML语句操作影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;在行级触发器中,使用:old和:new伪记录变量,识别值的状态。语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。

3、触发器的其他注意事项

触发器名与过程名和包的名字不一样,它是单独的名字空间,因而触发器名可以和表或过程有相同的名字,但在一个模式中触发器名不能相同。

DML触发器的限制:

(1)CREATE TRIGGER语句文本的字符长度不能超过32KB。

(2)触发器体内的SELECT语句只能为SELECT … INTO结构,或者为定义游标所使用的SELECT语句。

(3)触发器中不能使用数据库事务控制语句COMMIT、ROLLBACK语句。

(4)由触发器所调用的过程或函数也不能使用数据库事务控制语句。

(5)触发器中不能使用LONG、LONG RAW类型。

(6)触发器内可以参照LOB类型列的列值,但不能通过 :NEW 修改LOB列中的数据。

4、DML触发器基本要点

(1)触发时机:指定触发器的触发时间。如果指定为BEFORE,则表示在执行DML操作之前触发,以便防止某些错误操作发生或实现某些业务规则;如果指定为AFTER,则表示在执行DML操作之后触发,以便记录该操作或做某些事后处理。

(2)触发事件:引起触发器被触发的事件,即DML操作(INSERT、UPDATE、DELETE)。既可以是单个触发事件,也可以是多个触发事件的组合(只能使用OR逻辑组合,不能使用AND逻辑组合)。

(3)条件谓词:当在触发器中包含多个触发事件(INSERT、UPDATE、DELETE)的组合时,为了分别针对不同的事件进行不同的处理,需要使用ORACLE提供的如下条件谓词。

  • INSERTING:当触发事件是INSERT时,取值为TRUE,否则为FALSE。
  • UPDATING [(column_1,column_2,…,column_x)]:当触发事件是UPDATE时,如果修改了column_x列,则取值为TRUE,否则为FALSE。其中column_x是可选的。
  • DELETING:当触发事件是DELETE时,则取值为TRUE,否则为FALSE。

(4)解发对象:指定触发器是创建在哪个表、视图上。

(5)触发类型:是语句级还是行级触发器。

(6)触发条件:由WHEN子句指定一个逻辑表达式,只允许在行级触发器上指定触发条件,指定UPDATING后面的列的列表。

5、示例

(1)禁止在非工作时间插入数据。

create or replace trigger addEmpInfoCheck
 before insert on emp_info 
declare
begin

 if to_char(sysdate, 'day') in ('星期六', '星期日') or
 to_number(to_char(sysdate, 'hh24')) not between 9 and 18 then
 --禁止insert 
 raise_application_error(-20001,'非工作时间禁止插入数据!');
 end if;
end addEmpInfoCheck;

raise_application_error用于在plsql使用程序中自定义不正确消息。

该异常只在数据库端的子程序(流程、函数、包、触发器)中运用,而无法在匿名块和客户端的子程序中运用。

语法为raise_application_error(error_number,message[,[truefalse]])。

其中error_number用于定义不正确号,该不正确号必须在-20000到-20999之间的负整数;message用于指定不正确消息,并且该消息的长度无法超过2048字节。

(2)涨薪后的工资应该大于涨薪前的工资。

create or replace trigger checkSalary
 before update 
 on salary_info 
 for each row
declare
 --没有变量声明的话,declare可以省略
begin

 if :new.sal < :old.sal then
 raise_application_error(-20002,'涨后的薪水:'|| :new.sal ||'小于涨前的薪水:'||:old.sal);
 end if;
end checkSalary;

(3)创建基于值的触发器

create table xzw_test(info varchar2(256));

create or replace trigger addData
 after update
 on xzw_test 
 for each row
declare
begin

 if :new.sal > 6000 then 
 insert into xzw_test values(:new.sal ||'-'|| :new.username ||'-'|| :new.job);
 end if;

end addData;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • oracle date类型比较时间方式

    oracle date类型比较时间方式

    在Oracle数据库中比较DATE类型的时间部分,可以使用多种方法,包括使用TO_CHAR和时间格式提取时间部分、使用EXTRACT函数提取特定时间部分、使用INTERVAL进行时间比较以及转换为TIMESTAMP进行比较,每种方法都有其适用的场景,选择合适的方法取决于具体需求
    2025-02-02
  • 分享Oracle 11G Client 客户端安装步骤(图文详解)

    分享Oracle 11G Client 客户端安装步骤(图文详解)

    这篇文章主要介绍了分享Oracle 11G Client 客户端安装步骤(图文详解),非常具有实用价值,需要的朋友可以参考下。
    2016-12-12
  • 使用oracle发生标识符无效问题及解决

    使用oracle发生标识符无效问题及解决

    这篇文章主要介绍了使用oracle发生标识符无效问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • oracle数据库慢查询SQL实例详解

    oracle数据库慢查询SQL实例详解

    一般的业务系统如果遇到性能问题,绝大部分都是来自数据库的,有的业务一个查询执行时间好几秒,这就是我们说说的SQL慢查询,这篇文章主要给大家介绍了关于oracle数据库慢查询SQL的相关资料,需要的朋友可以参考下
    2024-06-06
  • Oracle执行计划及性能调优详解使用方法

    Oracle执行计划及性能调优详解使用方法

    在Oracle数据库中,通过使用EXPLAIN PLAN、AWR、SQL Trace等工具可以对SQL性能进行详细分析,EXPLAIN PLAN可以展示SQL执行计划和关键性能指标如操作类型、成本、行数等,本文给大家介绍Oracle执行计划及性能调优详解使用方法,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • Windows下Oracle JDK 17.0.18 安装+环境变量配置保姆级教程

    Windows下Oracle JDK 17.0.18 安装+环境变量配置保姆级教程

    本文基于Oracle官方JDK 17.0.18版本,整理了一套零基础也能看懂的安装+配置教程,适配Windows系统,亲测有效,感兴趣的朋友跟随小编一起看看吧
    2026-04-04
  • oracle区管理和段空间管理详细介绍

    oracle区管理和段空间管理详细介绍

    本文将详细介绍oracle区管理和段空间管理,需要的朋友可以参考下
    2012-11-11
  • 通过LogMiner实现Oracle数据库同步迁移

    通过LogMiner实现Oracle数据库同步迁移

    为了实现Oracle数据库之间的数据同步,网上的资料比较少的时候。最好用的Oracle数据库同步工具是:GoldenGate ,而GoldenGate是要收费的。这个时候就可以使用LogMiner来实现Oracle数据同步迁移,下面文章内容将给大家介绍其实现方法
    2021-09-09
  • Oracle数据迁移MySQL的三种简单方法

    Oracle数据迁移MySQL的三种简单方法

    对于许多企业而言,迁移数据库时最大的挑战之一是如何从一个数据库平台顺利迁移到另一个平台,下面这篇文章主要给大家介绍了关于Oracle数据迁移MySQL的三种简单方法,需要的朋友可以参考下
    2023-06-06
  • oracle使用order by排序null值如何处理

    oracle使用order by排序null值如何处理

    oracle 对查询结果进行排序时,被排序的栏位存在null值,且要指定NULL值排在最前面或者最后面,本文将介绍如何处理oracle 空值排序,需要的朋友可以参考下
    2012-11-11

最新评论