返回顶部
分享到

Oracle中的触发器(trigger)用法介绍

oracle 来源:互联网 作者:佚名 发布时间:2026-05-08 21:48:11 人浏览
摘要

1、触发器的定义 数据库触发器是一个与表相关联、存储PL/SQL语句的东西。 每当一个特定的数据操作语句(insert、update、delete)在指定的表上发出时,Oracle自动执行触发器中定义的语句序列。

1、触发器的定义

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

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

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

1

2

3

4

5

6

7

8

create or replace trigger empTrigger

 after insert on emp

 for each row

declare

 -- 这里存放本地变量

begin

 dbms_output.put_line('插入成功!');

end empTrigger;

2、触发器的语法

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

1

2

3

4

5

6

7

8

9

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)禁止在非工作时间插入数据。

1

2

3

4

5

6

7

8

9

10

11

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)涨薪后的工资应该大于涨薪前的工资。

1

2

3

4

5

6

7

8

9

10

11

12

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)创建基于值的触发器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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;


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • Oracle存储过程 procedure不允许使用return语句的解决
    Oracle存储过程中RETURN语句的使用存在严格限制:在存储过程(PROCEDURE)中不允许使用RETURN语句,否则会引发PLS-00372编译错误;而在函数(FUNCTIO
  • Oracle中的触发器(trigger)用法介绍
    1、触发器的定义 数据库触发器是一个与表相关联、存储PL/SQL语句的东西。 每当一个特定的数据操作语句(insert、update、delete)在指定的表
  • Oracle数据库高可用之DG+RAC介绍

    Oracle数据库高可用之DG+RAC介绍
    一、DG的概念和原理 Oracle Data Guard是Oracle数据库的一种高可用性解决方案,它通过在主数据库和一个或多个辅助数据库之间自动复制和同步数
  • Oracle归档日志爆满的急救指南
    作为运维工程师,你一定遇到过这样的紧急情况:/oracle/app/archivelog目录突然爆满,数据库挂起无法写入,业务全线中断。你慌忙执行了网上
  • Oracle授予普通用户kill session权限的方法
    开发A在测试环境操作时有时会遇到阻塞问题,需要找DBA帮忙查看阻塞会话及kill session,后来觉得太麻烦想要个kill会话的权限,查了下Oracl
  • Oracle日期时间查询方式
    一、查询近一个月的数据 如果是月份的话,oracle中可以使用add_months()函数来实现,如: 1 ADD_MONTHS(sysdate,-1) = CREATE_DATE 表示创建日期 CREATE_
  • Oracle登录时忘记用户名或密码该怎么解决
    (注意:Oracle12c规定用户名都必须以C##开头,否则无法使用。) 1.用户名:sys密码:change_on_install或者manager as sysdba 2.用户名:system密码:manager
  • Oracle记录登录用户IP的方法
    在运维场景中,在定位到某个SQL引起系统故障之后,想知道是哪台机器发过来的,方便定位源头,该如何解决? 在 Oracle 数据库中记录登录
  • 使用Oracle通过gateway连接MSSQL的流程

    使用Oracle通过gateway连接MSSQL的流程
    环境概述 某医院的his系统Oracle数据库要和体检系统进行数据通讯,需要从Oracle能查到sqlserver的数据。本次通过Oracle gateway来解决此问题。
  • oracle数据库被锁定的解除方案介绍

    oracle数据库被锁定的解除方案介绍
    oracle数据库被锁定如何解除 使用以下SQL语句查询Oracle被锁定的表 1 2 SELECT object_name, machine, s.sid, s.serial# FROM gv$locked_object l, dba_objects b, v$ses
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计