【postgresql初级使用】触发器的创建删除,你不知道的触发器函数中的系统变量,数据一致性还可以这样来保证

使用触发器

专栏内容

  • postgresql使用入门基础
  • 手写数据库toadb
  • 并发编程

个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

文章目录

  • 使用触发器
  • 概述
  • 创建触发器
    • 触发器函数
  • 删除触发器
  • 案例分析
    • 数据准备
    • 动作函数
    • 增加触发器
    • 触发结果
  • 总结
  • 结尾

概述


前一节介绍了触发器的原理,以及在postgresql中支持的触发器的类型,有基于行的触发器,也有基于SQL语句的触发器,同时触发的位置可以是执行前,也可以是执行后。

从本节开始介绍触发器的创建,使用,通过案例看看它们的什么样的区别。

创建触发器


触发器的创建语法如下:

CREATE TRIGGER trigger_name {BEFORE | AFTER} ON table_name[FOR [EACH] { ROW | STATEMENT }]EXECUTE { FUNCTION | PROCEDURE } trigger_function;

语法说明

  • 触发器创建使用关键字 create trigger, 然后指定触发器的名称;
  • 使用关键字before 或者 after来指定是在执行前或者执行后触发;
  • on指定触发器作用的表或视图;
  • 选择行触发器还是语句级触发器,行触发器使用for each row,而语句级触发器使用 for each statement; 当然each可以省略;
  • 最后指定动作执行函数;如果这里指定为function时,函数定义也必须为function,这里建议使用function, procedure是一种历史写法。

触发器函数

触发器的内容包含一个自定义的函数,所以首先得有一个执行动作的函数。

先来定义一个函数,如果触发就打印一条信息。

CREATE FUNCTION tri_fun() RETURNS TRIGGER LANGUAGE PLPGSQL
AS $$
BEGIN-- trigger logicraise notice 'trigger excute';
END;
$$
  1. 函数说明
  • 触发器使用的函数没有参数,在系统自动调用时会传入默认的参数;
  • 返回值类型必须为 trigger;
  1. 函数参数

在系统调用触发器函数时,会传入默认的参数,参数类型为TriggerData, 它的定义如下:

typedef struct TriggerData
{
NodeTag type;
TriggerEvent tg_event;
Relation tg_relation;
HeapTuple tg_trigtuple;
HeapTuple tg_newtuple;
Trigger *tg_trigger;
TupleTableSlot *tg_trigslot;
TupleTableSlot *tg_newslot;
Tuplestorestate *tg_oldtable;
Tuplestorestate *tg_newtable;
const Bitmapset *tg_updatedcols;
} TriggerData;

如果使用C语言或其它编程语言时,就可以直接访问此结构,如果使用plpgsql时,默认也定义了一组系统变量。

这些是您在 PostgreSQL 的行级触发器(row-level triggers)中可以访问的特殊变量。它们提供了关于触发器的元信息和触发触发器的事件的上下文。以下是这些变量的详细解释:

  1. NEW record

    • 描述:对于 INSERT/UPDATE 操作,这个变量包含将要插入或更新的新记录。在 DELETE 操作和语句级触发器(statement-level triggers)中,这个变量是 NULL。
    • 用途:可以在触发器中访问或修改将要插入或更新的记录。
  2. OLD record

    • 描述:对于 UPDATE/DELETE 操作,这个变量包含被更新或删除的旧记录。在 INSERT 操作和语句级触发器中,这个变量是 NULL。
    • 用途:可以在触发器中访问被更新或删除的记录。
  3. TG_NAME

    • 描述:触发器的名称。
    • 用途:可以用于日志记录或其他需要知道触发器名称的情况。
  4. TG_WHEN

    • 描述:触发器是在操作之前(BEFORE)还是之后(AFTER)触发,或者是替代(INSTEAD OF)操作。
    • 用途:决定触发器应该做什么,以及何时做。
  5. TG_LEVEL

    • 描述:触发器是行级(ROW)还是语句级(STATEMENT)。
    • 用途:确定如何在触发器中处理数据(逐行或整个语句)。
  6. TG_OP

    • 描述:触发触发器的事件类型:INSERT、UPDATE、DELETE 或 TRUNCATE。
    • 用途:决定触发器应该执行什么逻辑。
  7. TG_RELID

    • 描述:导致触发器调用的表的 object ID。
    • 用途:可以通过这个 ID 查找表的更多信息。
  8. TG_RELNAMETG_TABLE_NAME

    • 描述:这两个变量都表示导致触发器调用的表的名称。但 TG_RELNAME 已被弃用,并可能在未来的版本中消失。应使用 TG_TABLE_NAME
    • 用途:用于日志记录或需要知道哪个表触发了触发器的情况。
  9. TG_TABLE_SCHEMA

    • 描述:触发触发器的表的模式(schema)。
    • 用途:当您需要在多个模式中有相同表名的表之间区分时,这会很有用。
  10. TG_NARGSTG_ARGV

    • 描述TG_NARGS 表示在 CREATE TRIGGER 语句中给触发器函数提供的参数数量。TG_ARGV 是一个文本数组,其中包含这些参数。
    • 用途:使触发器更加灵活,可以根据传递给它的参数执行不同的逻辑。

这些特殊变量在编写 PostgreSQL 触发器时非常有用,因为它们提供了关于触发器和触发触发器的事件的上下文信息。

删除触发器


触发器删除就比较简单了,语法如下:

DROP TRIGGER trigger_name 
ON table_name 
[ CASCADE | RESTRICT ];

语法说明

  • 使用drop 命令,指定触发器名称与触发器对应的表即可;
  • 如果有级联,可以指定cascade进行级联删除。

案例分析


下面来通过一个案例,看看触发器的效果。

数据准备

先来建一张表emp, 然后通过触发器检查数据的一致性,并且将插入数据的日期和用户名进行记录。

CREATE TABLE emp (empname text,salary integer,last_date timestamp,last_user text
);

动作函数

使用plpgsql语言编写执行函数。

CREATE FUNCTION emp_stamp() 
RETURNS trigger AS $emp_stamp$
BEGIN-- Check that empname and salary are givenIF NEW.empname IS NULL THENRAISE EXCEPTION 'empname cannot be null';END IF;IF NEW.salary IS NULL THENRAISE EXCEPTION '% cannot have null salary',NEW.empname;END IF;-- Who works for us when they must pay for it?IF NEW.salary < 0 THENRAISE EXCEPTION '% cannot have a negative salary',NEW.empname;END IF;-- Remember who changed the payroll whenNEW.last_date := current_timestamp;NEW.last_user := current_user;RETURN NEW;
END;
$emp_stamp$ LANGUAGE plpgsql;

这里使用了new系统参数值,它们分别代表插入前的新值,这里可以改变它的内容。

增加触发器

创建一个before触发器,在数据真正修改前做校验,并修改其中的内容,在insertupdate动作进行触发。

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
FOR EACH ROW EXECUTE FUNCTION emp_stamp();

这是一个行级触发器,每一行数据的插入和更新都会触发。

触发结果

自动赋值

这里只需要插入前两个字段就可以,后两个字段会被自动赋值。

postgres=> insert into emp(empname,salary) values('alex',4000);
INSERT 0 1
postgres=> select * from emp;empname | salary |         last_date          | last_user
---------+--------+----------------------------+-----------alex    |   4000 | 2024-06-04 08:43:54.428469 | senllang
(1 row)

可以看到后两个字段被自动赋值,用户采用当前登陆的用户名。

一致性校验

如果插入的数据不符合设计要求,在触发器中进行检查时会抛出异常;

postgres=> insert into emp(empname,salary) values('white',-1);
ERROR:  white cannot have a negative salary
CONTEXT:  PL/pgSQL function emp_stamp() line 15 at RAISE

触发器中抛出异常后,事务也就会被abort掉。

总结


本文主要分享了触发器的创建,删除,以及触发器函数定义和系统变量,触发器中的系统变量可以帮助我们获取触发器当前的环境信息。

适当的使用触发器可以将应用变得简单,现在也流行减少函数和存储过程,为了更好的移植性和维护性。

结尾


非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/22068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis之常用实战场景

1.Redis数据丢失场景 1.1 持久化丢失 采用RDB或者不持久化&#xff0c;就会有数据丢失&#xff0c;因为是手动或者配置以快照的形式来进行备份。 解决: 启用AOF&#xff0c;以命令追加的形式进行备份&#xff0c;但是默认也会有1s丢失&#xff0c;这是在性能与数据安全性中寻…

K-means聚类模型算法

K-means聚类是一种无监督的机器学习算法&#xff0c;用于将数据点划分到K个不同的簇中。这种算法的目标是最小化簇内的方差&#xff0c;即使得每个簇内的数据点与簇中心的距离尽可能小。以下是K-means聚类模型的主要步骤和特点&#xff1a; 主要步骤&#xff1a; 1. 选择K值&…

深入解析Spring Cloud Config:构建高可用分布式配置中心

在微服务架构中&#xff0c;配置管理是一个关键问题。Spring Cloud Config提供了一种解决方案&#xff0c;它是一个高可用、分布式的外部配置中心。本文将深入探讨Spring Cloud Config的原理、架构及其在实际项目中的应用&#xff0c;帮助读者掌握如何构建一个高效、可靠的分布…

SD NAND(贴片式TF卡)在储能领域的应用

储能系统&#xff08;Energy Storage System&#xff0c;简称ESS&#xff09;是指能将电能以化学能、势能、动能等形式储存起来&#xff0c;并在需要时将其转化为电能供应给用户的设备。主要由电池管理系统&#xff08;BMS&#xff09;、能量管理系统&#xff08;EMS&#xff0…

拿到Offer了才知道,这家公司年终奖只有几百块~

我也挠头了 最近又有不少粉丝上岸了&#xff0c;其中一位分享的事情比较有意思&#xff0c;和你分享一下&#xff1a; 以后你对比Offer的时候也可以多个经验。 事情是这样的&#xff1a; 他在经过2个多月空窗期之后终于拿到了Offer&#xff0c;月薪涨幅不大&#xff0c;但是…

java的clone

一、clone的用法&#xff1a; package chatRoom.F5;class Person implements Cloneable{//1.public String name;public Person(String name) {this.name name;}//2.protected Person clone() throws CloneNotSupportedException {return (Person)super.clone();//重写Object…

linux脚本执行报错|syntax error near unexpected token `$‘do\r‘‘

一、问题 在Window上用记事本txt写了个linux脚本&#xff0c;放到Linux上去执行报错|syntax error near unexpected token $‘do\r‘‘ 二、可通过vim的-b命令查询脚本&#xff08;-b表示二进制模式&#xff09; vim -b youtest.sh 发现&#xff0c;sh脚本后面多了^M 三、…

媒体有入口,发稿有入口 是什么意思?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体有入口&#xff0c;发稿有入口是指在新闻媒体发稿时&#xff0c;稿件可以通过一定的路径被访问和浏览。具体来说&#xff0c;有入口的新闻稿件可以通过点击链接&#xff0c;逐步深入…

芯片验证分享1 —— 开篇及名词解释

大家好&#xff0c;我是谷公子的藏经阁&#xff0c;今天和大家很高兴能和大家分享的是芯片验证中的一些内容&#xff0c;希望对大家的日常工作有所帮助&#xff0c;如果这些内容有帮助到大家的话&#xff0c;那么此次的分享就很值得。另外&#xff0c;对于这个课题&#xff0c;…

揭开旅游卡项目!是当下趋势风潮?来这给你整明白!

旅游卡作为一种旅游产品&#xff0c;近年来在市场上逐渐流行起来。它通常包含一系列旅游服务&#xff0c;如门票、住宿、餐饮、交通等&#xff0c;旨在为消费者提供一站式的旅游体验。在您所描述的案例中&#xff0c;云南6天五晚游旅游卡以极低的价格吸引消费者&#xff0c;并通…

ChatTTS增强版,增强音质、批量处理、固定音色、支持长文本

大家好&#xff0c;最近ChatTTS文字生成语音项目挺火。只需要输入一段文字&#xff0c;就可以生成一段非常逼真的声音。声音的效果非常不错。它支持英文和中文两种语言。我在原版的基础上做了一些改动&#xff0c;整合包分享给大家。 功能介绍 除了基础的文本生成音频功能以外…

实验10 RIP协议配置

实验10 RIP协议配置 一、原理描述二、RIPv1配置&#xff08;一&#xff09;实验目的&#xff08;二&#xff09;实验内容&#xff08;三&#xff09;实验配置&#xff08;四&#xff09;实验步骤 三、 RIPv2配置&#xff08;一&#xff09;实验目的&#xff08;二&#xff09;实…

IT闲谈——什么是容器?

目录 什么是容器一、容器的起源与发展二、目前使用较多的容器三、容器能用来做什么四、容器的应用场景 什么是容器 随着云计算和微服务的兴起&#xff0c;容器技术逐渐成为IT行业的热门话题。容器&#xff0c;简而言之&#xff0c;是一种轻量级的、可移植的、独立的软件包&…

windows 使用脚本 批量将一个文件夹下面 子文件夹下的视频文件拷贝到另一个文件下

如果想要在Windows上使用脚本&#xff08;比如批处理脚本 .bat&#xff09;来复制指定文件夹下所有子文件夹中的视频文件到另一个目标文件夹&#xff0c;可以使用以下的批处理脚本示例&#xff1a; echo off setlocal enabledelayedexpansion :: 设置源文件夹和目标文件夹的…

职称继续教育--专业课6

单选题&#xff08;共20题&#xff0c;每题1.5分&#xff09; 1、新型城镇化改革试点的总体要求是&#xff1a;以人的城镇化为核心&#xff0c;以&#xff08;&#xff09;为关键&#xff0c;大胆探索&#xff0c;试点先行。 A、提升质量 2、根据本讲&#xff0c;建设和管理城…

cesium 之 flyTo、setView、lookat

orientation配置项的参数 cesium中&#xff0c;朝向orientation&#xff0c;通常使用heading、pitch、roll这三个参数来描述 heading 通过调整heading的值&#xff0c;使相机朝向特定的方向朝向方向说明【北&#xff1a;0&#xff0c; 东&#xff1a;π/2弧度&#xff0c; …

Keras深度学习框架实战(6):使用CNN-RNN架构实现视频分类

1、绪论 1.1 CNN-RNN概述 1.1.1 结构组成 CNN-RNN架构结合了卷积神经网络&#xff08;CNN&#xff09;和循环神经网络&#xff08;RNN&#xff09;两种不同类型的神经网络结构。 卷积神经网络&#xff08;CNN&#xff09;&#xff1a; 主要用于处理具有网格状拓扑结构的数据…

VLM学习笔记

目录 基础VLM模型CLIP CLIP (Contrastive Language-Image Pre-training) clip的再训练 CLIP-Chinese 轻量化VLM探索&#xff1a;MobileVLM V2 怎么预训练VLMs&#xff1f; TurboMind LLM推理引擎 基础VLM模型CLIP CLIP (Contrastive Language-Image Pre-training) 基本…

【Python】轻松打包:CentOS7上使用PyInstaller将Shell脚本转换为可执行文件的完美指南

【Python】轻松打包&#xff1a;CentOS7上使用PyInstaller将Shell脚本转换为可执行文件的完美指南 大家好 我是寸铁&#x1f44a; 总结了一篇【Python】轻松打包&#xff1a;CentOS7上使用PyInstaller将Shell脚本转换为可执行文件的完美指南✨ 喜欢的小伙伴可以点点关注 &#…

【CXL协议-控制和状态寄存器(8)】

8.0 控制和状态寄存器 Compute Express Link 设备控制和状态寄存器被映射到单独的空间&#xff1a;配置空间和内存映射空间。配置空间寄存器使用配置读取和配置写入进行访问。内存映射寄存器使用内存读取和内存写入进行访问。表 123 总结了本章中定义的寄存器位的属性。除非另…