Oracle数据库 触发器

article/2025/10/24 21:41:55

文章目录

  • 一、触发器的定义
  • 二、触发器的分类
  • 三、触发器的功能
  • 四、触发器的语法
  • 五、触发器的使用案例
    • 案例1:向emp1表中插入一条数据后输出 欢迎加入 语句
    • 案例2:数据校验,在周四这一天不允许向emp1表中插入/更新数据
    • 案例3:创建触发器,记录表的删除数据
    • 案例4:创建触发器,记录表的更新数据
    • 案例5:创建触发器,在删除某条数据之前先在记录表插入该条数据

一、触发器的定义

触发器:当某个条件成立的时候,触发器中所定义的语句就会被自动执行。

二、触发器的分类

触发器分为语句级触发器行级触发器
语句级触发器:在某些语句执行前或执行后被触发。
行级触发器:在定义了触发器的表中的行数据改变时就会被触发一次。

三、触发器的功能

  1. 允许or限制对表的修改
  2. 自动生成派生列,比如自增字段(序列)
  3. 强制数据一致性
  4. 提供审计和日志记录
  5. 防止无效的事务处理
  6. 启用复杂的业务逻辑

四、触发器的语法

create [or replace] trigger 触发器名称 触发时间 触发事件
on 表名
[for each row]
beginPL/SQL语句块
end;

语法解释:
触发器名称:触发器对象的名称,没有实际用途。
触发时间:指定触发器何时执行,有beforeafter两个值。
before:在数据库动作之前执行触发器
after:在数据库动作之后执行触发器
触发事件:指明哪些数据库动作会触发该触发器
insert 数据库插入时会触发该触发器
update 数据库更新时会触发该触发器
delete 数据库删除时会触发该触发器
表名:数据库触发器所在的表
for each row:对触发器的执行范围做限定,对表的每一行触发器执行一次,如果没有这个选项就是对整个表执行一次

五、触发器的使用案例

前提:拷贝emp表为emp1表,案例1和案例2均在emp1表中执行。

create table emp1 as select * from emp;

案例1:向emp1表中插入一条数据后输出 欢迎加入 语句

--创建触发器
create or replace trigger trigger1 after insert
on emp1
begindbms_output.put_line('欢迎加入');
end;
--插入数据,触发触发器的执行
insert into emp1(empno,ename) values(0001,'小曹同学');

效果如下:
在这里插入图片描述

案例2:数据校验,在周四这一天不允许向emp1表中插入/更新数据

--创建触发器
create or replace trigger trigger2 before insert or update 
on emp1
declarev_day varchar2(20);
begin---判断今天是否是星期四select to_char(sysdate,'day') into v_day from dual;---判断if v_day = '星期四' thendbms_output.put_line('今天是星期四,不能插入/更新数据');raise_application_error(-20001,'今天不能插入/更新数据!');end if;
end;
--插入/更新数据,触发触发器的执行
insert into emp1(empno,ename) values(0002,'小曹同学');
update emp1 set sal = 8888 where empno = 0001;

效果图如下:
在这里插入图片描述

案例3:创建触发器,记录表的删除数据

先创建一个测试表,此处我创建了一个employee表,共有四个字段。创建表后插入4条数据,并拷贝employee表为employee_log作为删除数据记录表。
当以上准备工作完成后,创建触发器并测试。

--创建employee表
create table employee(id varchar2(4),name varchar2(15),age varchar2(3),sex varchar2(4)
)
--插入数据
insert into employee values('e101','小曹同学',20,'女');
insert into employee values('e102','小曹同学2',21,'女');
insert into employee values('e103','小曹同学3',20,'女');
insert into employee values('e104','小曹同学4',19,'男');
commit;
--创建employee_log表作为删除操作记录表
create table employee_log as select * from employee;--创建触发器
create or replace trigger trigger3 after delete 
on employee
for each row
begininsert into employee_log values(:old.id,:old.name,:old.age,:old.sex);
end;
--测试
delete employee;
--查询记录表
select * from employee_log;

结果图如下:
在这里插入图片描述

案例4:创建触发器,记录表的更新数据

--创建测试表
create table test(tid number(4),tname varchar(20),tage number(2),tsex char
);
--创建日志记录表
create table test_log(l_user varchar2(15),l_type varchar2(15),l_date varchar2(20)
);
--创建触发器
create or replace trigger trigger4 after delete or insert or update
on test
declarev_type test_log.l_type%type;
beginif deleting thenv_type := 'delete';dbms_output.put_line('记录已经成功删除并记录到日志');elsif inserting thenv_type := 'insert';dbms_output.put_line('记录已经成功插入并记录到日志');elsif updating thenv_type := 'update';dbms_output.put_line('记录已经成功更新并记录到日志');end if;insert into test_log values(user,v_type,to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
end;
--测试
insert into test values(1,'小红',22,'M');
update test set tage=30 where tid=1;
delete test;
--查询记录表
select * from test_log;

我是测试了三次测试语句,故有九条记录:
在这里插入图片描述

案例5:创建触发器,在删除某条数据之前先在记录表插入该条数据

--创建测试表和测试日志表
create table test01(t_id number(4),t_name varchar2(20),t_age number(2),t_Sex char
);
create table test01_log as select * from test01;
--向测试表中插入数据
insert into test01 values(1,'小曹同学',20,'M');
insert into test01 values(2,'小曹同学2',20,'M');
insert into test01 values(3,'小曹同学3',20,'M');
commit;
--创建触发器
create or replace trigger trigger5 before delete on test01
for each row --行级触发器
begininsert into test01_log values(:old.t_id,:old.t_name,:old.t_age,:old.t_sex);
end;
--测试
delete test01 where t_id=3;
commit;
--查询日志表
select * from test01_log;

结果图如下:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/0QBZniyu.shtml

相关文章

数据库之触发器详解

一、触发器的概念 触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性。 举个例子,比如你现在有两个表【用户表】和【日志表】,当一个…

数据库-触发器

目录 1. 触发器概述 2. 触发器的创建 2.1 创建触发器语法 3. 查看、删除触发器 3.2 删除触发器 4. 触发器的优缺点 4.2 缺点 4.3 注意点 在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如 商品信息 和 库存信…

触发器(数据库必学)

文章目录 概念注意 优缺点优点缺点 语法参数说明 查看触发器删除触发器实例实际应用注意重新编辑拓展不能对同一张表进行修改 概念 触发器是一种特殊类型的存储过程,它不同于存储过程,主要是通过事件触发而被执行的。而存储过程则需要主动调用其名字执行…

C语言实现字符串逆序、倒置字符串(字符串逆序问题的升级)

一.字符串逆序 问题描述&#xff1a; 输入一个字符串str&#xff0c;将其内容颠倒过来&#xff0c;并输出。 数据范围0<len(str)<10000 输入描述&#xff1a; 输入一个字符串&#xff0c;可以有空格 输出描述&#xff1a; 输出逆序的字符串 输入样例&#xff1a; …

指针实现字符串逆序

代码如下&#xff1a; #include<stdio.h> #include<string.h> void reverse(char* str) { //指针变量分别指向第一个和最后一个元素&#xff0c;借助中间变量temp进行交换。char* left str;char* right str strlen(str) - 1;while (left < right){char temp…

c语言字符串逆序输出reverse,将一个字符串逆序输出

C语言:输入一个字符串,然后逆序输出 输入一个字符串,然后逆序输出,要CSS布局HTML小编今天和大家分享主函数调用fun函数,fun的功能是逆可以将整数当做字符串(字符串长度不超过10)接收,然后反向输出字符数组元素即可。 字符串实际长度可以用strlen函数来计算。 方法程序如下…

字符串逆序输出

字符串逆置 方法1:下标法&#xff0c;定义一个i下标从头开始&#xff0c;使用strlen函数求出字符串长度(不包括\0),定义一个j下标等于字符串长度减一&#xff0c;i&#xff0c;j下标字符进行交换&#xff0c;只需要遍历字符串长度一半即可 方法2:额外创建一个数组&#xff0c…

递归实现字符串逆序

编写一个函数 reverse_string(char * string)&#xff08;递归实现&#xff09;&#xff0c;将参数字符串中的字符反向排列&#xff0c;不是逆序打印。 &#xff08;要求&#xff1a;不能使用C函数库中的字符串操作函数。&#xff09; &#xff08;在本次练习中&#xff0c;由于…

C字符串逆序、C++字符串逆序

1.C字符串逆序&#xff1a; void CReverse(char* ch) {int nLen strlen(ch) - 1;char szStr;for (int i 0; i < nLen - i; i){szStr ch[i];ch[i] ch[nLen - i];ch[nLen - i] szStr;}ch[nLen 1] 0; } 2.C字符串逆序&#xff08;利用栈的先进后出的原理&#xff09; …

字符串逆序 - 多种方法实现

字符串逆序实现方法 1. 借助额外数组2. 循环实现2.1 图解2.2 思路2.3 代码实现 3. 递归实现14. 递归实现24.1 思路 对字符串进行逆序&#xff0c;以字符串abcdef为例 1. 借助额外数组 #include <stdio.h> #include <string.h>int main() {char str[] "abcd…

字符串逆序的几种写法

字符串逆序的几种写法 提示&#xff1a;将字符串逆序与将其逆序打印出来是两码事&#xff0c;逆序是将内容倒着改变了&#xff0c;逆序打印虽然打印结果也是倒着的&#xff0c;不过储存字符串的数组内容并没有改变。 一、非递归写法 1. 将一个给定的字符串abcdef逆序 #incl…

字符串逆序(递归实现)

目录 一、代码实现&#xff1a; 二、代码逐步实现过程&#xff1a; 1、不用递归用循环方式实现&#xff1a; 1、使用库函数&#xff1a; 2、不使用库函数&#xff1a; &#xff08;1&#xff09;使用参数是数组的形式&#xff1a; &#xff08;2&#xff09;使用参数是指…

【C语言刷题】字符串逆序

目录 一、字符串逆序&#xff08;基础题&#xff09; 1.一个经典的错误&#xff0c;标准的零分 2.采用gets函数来修补漏洞 3.非要使用scanf怎么办&#xff1f; 4.使用指针来实现逆序函数 5.将函数修改为&#xff0c;只要传入两个地址&#xff0c;就能逆序这两个地址之间的…

使用C语言实现字符串逆序操作

这篇文章主要介绍了使用C语言实现字符串逆序操作案例,本文包含使用C语言的两种方法去实现,递归和非递归,以下就是详细内容,需要的朋友可以参考下 编写一个函数 reverse_string(char * string) 实现&#xff1a;将参数字符串中的字符反向排列。 要求&#xff1a;不能使用C函数库…

C语言实现——字符串逆序

目录 前言 如何实现 代码实现 1.设立一个数组存放输入的字符串 2.将输入的字符串整体逆序 2.1 计算字符串长度 2.2 使用函数来实现倒置 2.3 实现函数reverse 3.将其中每个单词再进行逆序 3.1 整个语句如何结束循环 3.2 每个单词的结束位置 3.3 内部实现 3.4 判断…

dtb展开成device_node

dtb展开成device_node 文章目录 dtb展开成device_node设备树是如何传递给内核的&#xff1f;设备树相关结构体举例of操作函数与查找节点有关的 OF 函数1、of_find_node_by_name 函数2、of_find_node_by_type 函数3、of_find_compatible_node 函数4、of_find_matching_node_and_…

设备树之DTS与DTB格式

目录 一、设备树 二、DTS格式 2.1 属性 2.2 节点 2.3 引用其他节点 2.4 小总结 三、DTB格式 3.1 结构 3.2 分析 一、设备树 对于点灯字符设备驱动程序可以有三种写法&#xff0c;首先是传统方法&#xff0c;这种方式直接在程序中写死&#xff0c;其次是利用总线设备驱…

Android boot.img dtb.img 编译过程

最近做RK3588案子,修改dts后,导致boot.img过大,编译出错,整体分析下boot.img过大的原因是因为在打包boot.img过程中,dbt.img过大导致,所以整体分析下boot.img编译过程,尤其是dbt.img的生成过程. boot.img生成过程 在Andorid跟目录下执行, source build/envsetup.sh 然后lunch x…

Linux 设备树(二) dtc dts/dtsi dtb的关系

在学习设备树之前&#xff0c;我们先来了解一下跟设备树相关的三个对象&#xff0c;分别是dtc、dts/dtsi、dtb。 dtc:用来编译设备树的工具 dts:设备树描述文件 dtsi:设备树头文件 dtb:编译后的二进制文件 dtc设备树编译工具 dtc是用来编译设备树的工具&#xff0c;就像gcc可以…

dtb如何转换到platform_device

分2步&#xff0c;第一步是首先转换为device_node&#xff0c;第二步device_node转换为platform_device。 第一步 /*** unflatten_device_tree - create tree of device_nodes from flat blob** unflattens the device-tree passed by the firmware, creating the* tree of st…