Oracle中的触发器(trigger)

2023-10-30

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提供的如下条件谓词。
       1)INSERTING:当触发事件是INSERT时,取值为TRUE,否则为FALSE。
       2)UPDATING [(column_1,column_2,…,column_x)]:当触发事件是UPDATE时,如果修改了column_x列,则取值为TRUE,否则为FALSE。其中column_x是可选的。
       3)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;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oracle中的触发器(trigger) 的相关文章

随机推荐

  • Ubuntu-22.04通过RDP协议连接远程桌面

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 RDP是什么 二 配置 1 打开远程桌面功能 2 验证服务 3 防火墙配置 4 测试效果 总结 前言 由于一些特殊需要 我需要通过远程桌面连接到Ubunt
  • 0-1背包问题和完全背包问题

    先总体介绍一下0 1背包和完全背包的区别 主要是01背包和完全背包 背包九讲里面的其他背包问题 都是竞赛级别的 leetcode上面没有 01背包就是 背包存在一个最大容量V 每个物品有两个参数 体积w和价值v 目的是在不超过背包最大容量的
  • 利用 mysql.help_topic 生成序列

    有时我们在生成一些时间轴类似的数据时 要求数据库不管有没有指定天的数据 都要生成该时间节点 可用mysql help topic来解决生此类问题 通过序列和日期函数相结合来满足我们的业务需求 mysql 生成序列 利用 mysql help
  • spark学习2:spark运行基本架构

    各个名词介绍 1 RDD 弹性分布式数据集 2 DAG 有向无环图 反应各RDD之间关系 即把第一个RDD和最后一个RDD 串联起来的关系图 根据DAG 能够找到每个RDD的父RDD 3 executor executor是 驻守在各个工作
  • 三维重建可以考虑光线跟踪的方法

    如题
  • LeetCode 之 剑指 Offer 12. 矩阵中的路径(Java)

    文章目录 LeetCode 之 剑指 Offer 12 矩阵中的路径 Java 一 题目 二 解题思路 三 代码 LeetCode 之 剑指 Offer 12 矩阵中的路径 Java 一 题目 剑指 Offer 12 矩阵中的路径 给定一个
  • Nacos搭建集群

    复制三份Nacos服务端文件 配置相同的数据库 参考前面nacos上线文档 修改每一个的application properties文件内的 server port 然后在每个conf文件夹内新增 cluster conf文件 文件内容为
  • python写ecxel。多个条件对Excel中的数据进行筛选并处理

    在第很多行中 D列不空 C列不空 那么A列B列E列F列不空 D列空 C列不空 那么A列B列E列F列空 import pandas as pd def process data filename 读取Excel文件 df pd read ex
  • Android 反编译三种方式

    首先反编译别人的APK 主要是学习别人的实现逻辑 给自己一个思路 比较商业的APK也不会给你留下这个漏洞 一些核心的业务处理会在后台进行操作 本地的 APK 也会进行混淆加密等 好了废话不多说 步入正题 方法一 在线反编译 很简单方便的一个
  • 思科路由器配置

    1 路由表 show IP route 用户模式 特权模式 enable 全局配置模式 configure terminal config 配置主机名称 enable configure terminal config hostname t
  • RuntimeError: cuDNN error: CUDNN_STATUS_INTERNAL_ERROR

    torch backends cudnn benchmark True 加在开头
  • MySQL基础学习(四)——SQL语句之DML语句

    前言 上一篇博客介绍了一下SQL语句中的DDL和DCL语句 主要涉及通过SQL赋予或者撤回相关的用户权限 创建数据表 创建索引等内容 这一篇博客开始总结DML语句 就是我们开发中常用的一些select insert update delet
  • C#常见编程

    1 编写一段程序 运行时向用户提问 你考了多少分 0 100 接受输入后判断其等级并显示出来 判断依据如下 等级 优 90 100分 良 80 89分 中 60 69分 差 0 59分 static void Main string arg
  • 合并两个有序链表(easy)

    将两个升序链表合并为一个新的 升序 链表并返回 新链表是通过拼接给定的两个链表的所有节点组成的 示例 1 输入 l1 1 2 4 l2 1 3 4 输出 1 1 2 3 4 4 示例 2 输入 l1 l2 输出 示例 3 输入 l1 l2
  • 【Golang源码学习】chromedp篇

    GitHub https github com chromedp chromedp chromedp go RunResponse 官方注释 func RunResponse ctx context Context actions Acti
  • WKWebView之离线加载以及遇到的问题

    目录 前言 一 离线包是什么 二 方案调研 NSURLProtocol WKURLSchemeHandler 三 具体实施 1 离线包的分发 2 服务器对请求接口处理 3 客户端下载离线包 4 webview设置拦截 5 WKURLSche
  • Typcho反序列化漏洞分析

    Typcho反序列化漏洞分析 文章首发 https xz aliyun com t 9428 影响范围 2017年10月24日之前的所有版本 环境搭建 下载地址 http typecho org 这里主要是说下 在intall之前 需要我们
  • Linux Ubuntu搭建Git服务器

    之前介绍过如何在Windows上搭建Git仓库服务器 不过服务器用的比较多的还是Linux 因为便宜 同一个VPS商一般来说Linux比Windows便宜 没有图形界面 低配置VPS的也可以跑动Linux 开源免费 我感觉比较灵活 下载源也
  • 创建对象的五种方式

    1 使用new关键字 gt 调用构造函数 2 使用Class的newInstance方法 gt 调用构造函数 3 使用Constructor的newInstance方法 gt 调用构造函数 4 使用clone方法 gt 没有调用构造函数 5
  • Oracle中的触发器(trigger)

    1 触发器的定义 数据库触发器是一个与表相关联 存储PL SQL语句的 东西 每当一个特定的数据操作语句 insert update delete 在指定的表上发出时 Oracle自动执行触发器中定义的语句序列 例如 当员工信息插入后 自动