【postgresql初级使用】条件表达式触发器,兼顾DML执行性能,又能执行复杂逻辑,只在结帐时计算总帐

条件触发器

专栏内容

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

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

文章目录

  • 条件触发器
  • 概述
  • 原理机制
    • 语法
    • 原理
  • 案例
    • 场景介绍
    • 数据准备
    • 创建触发器
    • 效果验证
  • 总结
  • 结尾

概述


触发器trigger 是语句级的(row-level) 时, 被触发的频率是相当高的,会带来一定的性能开销。

今天给大家分享一种带有条件表达式的触发器,只在条件满足时触发,其它情况下并不会执行,这样既能满足触发器的复杂处理,也能满足性能的要求。

原理机制


下面就来详细了解一下带条件表达式的触发器吧。

语法

带条件表达式的触发器的SQL语法格式如下:

CREATE TRIGGER trigger_name
{BEFORE | AFTER} { INSERT OR UPDATE OR DELETE OR TRUNCATE }
ON table_name
WHEN condition
FOR [EACH]  ROW 
EXECUTE FUNCTION function_name();

说明

  • 这里与普通触发器的语法类似,可以参见前面的分享;
  • 如果是行级的触发器,需要指定BEFOREAFTER以及对应的事件;
  • 此处通过WHEN子句指定触发的条件,只有在条件满足时才能执行;
  • 触发器类型指定,行级触发器为FOR EACH ROW
  • 最后指定触发器执行函数;

原理

在行级触发器中:

  • 可以访问修改前的行与修改后的行,通过访问这两行的值设定条件表达式。
  • 修改前的行使用OLD.column_name进行引用,修改后的行引用方式为 NEW.column_name;
  • INSERT命令没有OLD行,DELETE命令没有NEW行;
  • INSTEAD OF不支持设置条件;

而在语句级触发器中没有可引用的行数据。

案例


下面我们通过一个案例来看看条件触发器的使用场景。

场景介绍

当在饭店消费时,会先点一些菜,过程中又会根据需要再加一些菜或者饮品,最后再统一结帐。

对于这样一个很常见的场景,通过条件触发器可以实现自动计算账单。

数据准备

新建两张表,一张为订单表,记录客户消费情况,以及订单状态;另一张为客户统计,记录客户总的消费金额。

CREATE TABLE orders (order_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,customer_id INT NOT NULL,total_amount NUMERIC NOT NULL DEFAULT 0,status VARCHAR(20) NOT NULL
);CREATE TABLE customer_stats (customer_id INT PRIMARY KEY,total_spent NUMERIC NOT NULL DEFAULT 0
);

创建触发器

下面在orders表上对insert,update事件创建两个触发器。

创建订单触发器

当有新客人时,会向orders表中插入一条新记录;

此时通过触发器自动在customer_stats表中也插入客户ID,金额为0,此时订单状态还为pending

CREATE OR REPLACE FUNCTION insert_customer_stats()
RETURNS TRIGGER 
AS $$
BEGININSERT INTO customer_stats (customer_id)VALUES (NEW.customer_id);RETURN NULL;
END;
$$ LANGUAGE plpgsql;CREATE TRIGGER insert_customer_stats_trigger
AFTER INSERT ON orders
FOR EACH ROW
EXECUTE FUNCTION insert_customer_stats();

结帐付款

客人在过程中可能会变动订单金额,订单状态始终为pending, 最后结帐时将订单状态改为completed,此时生成帐单。

orders表上增加UPDATE事件的条件触发器,只有NEW.statuscompleted时才会触发,此时将客户金额插入customer_stats表中。

CREATE OR REPLACE FUNCTION update_customer_stats()
RETURNS TRIGGER 
AS 
$$
BEGINIF NEW.status = 'completed' THEN-- Update the total_spent for the customerUPDATE customer_statsSET total_spent = total_spent + NEW.total_amountWHERE customer_id = NEW.customer_id;END IF;RETURN NULL;
END;
$$ LANGUAGE plpgsql;CREATE TRIGGER update_customer_stats_trigger
AFTER UPDATE ON orders
FOR EACH ROW
WHEN (OLD.status <> 'completed' AND NEW.status = 'completed')
EXECUTE FUNCTION update_customer_stats();

效果验证

好了,来测试一下业务流。

先来了两波客人,分别点了100,200的菜品。

INSERT INTO orders (customer_id, total_amount, status)
VALUES(1, 100, 'pending'),(2, 200, 'pending');

两波客人都要结帐了,要忙了。

UPDATE orders
SET status = 'completed'
WHERE customer_id IN (1,2);

看一下这两波客人的账单:

postgres=> SELECT * FROM customer_stats;customer_id | total_spent
-------------+-------------1 |         1002 |         200
(2 rows)
先生/女士,这是您的账单,请您过目... 请慢走,欢迎下次光临!

总结


本章节分享了通过表达式条件来限制触发器执行,这样不仅提升DML操作的性能,同时还能利用触发器实现复杂的功能。

最后通过一个经典的帐单结算的案例,演示了条件触发器,会在订单转为完成状态时自动生成帐单。

结尾


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

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

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

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

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

相关文章

【docker入门】

在软件开发过程中&#xff0c;环境配置是一个至关重要的步骤&#xff0c;它不仅影响开发效率&#xff0c;也直接关联到软件的最终质量。正确的环境配置可以极大地减少开发中的潜在问题&#xff0c;提升软件发布的流畅度和稳定性。以下是几个关键方面&#xff0c;以及如何优化环…

【机器学习】第6章 支持向量机(SVM)

一、概念 1.支持向量机&#xff08;support vector machine&#xff0c;SVM&#xff09;&#xff1a; &#xff08;1&#xff09;基于统计学理论的监督学习方法&#xff0c;但不属于生成式模型&#xff0c;而是判别式模型。 &#xff08;2&#xff09;支持向量机在各个领域内的…

如何在不丢失数据的情况下解锁安卓手机密码

手机是我们生活中必不可少的工具&#xff0c;可以帮助我们与朋友和家人保持联系&#xff0c;了解最新消息&#xff0c;甚至经营我们的业务。然而&#xff0c;当我们在 Android 手机或 iPhone 上设置密码时&#xff0c;我们经常会忘记密码&#xff0c;或者根本没有设置密码。当这…

IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照(snapshot)JAR 包

IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照&#xff08;snapshot&#xff09;JAR 包 目录 IntelliJ IDEA 使用 Maven 时不加载本地私服的最新版本快照&#xff08;snapshot&#xff09;JAR 包1. 检查 settings.xml2. IDEA Maven 配置3. 强制更新 Snapshot4. 使用…

学习笔记——路由网络基础——路由度量值

3、路由度量值 (1)基本概念 路由度量值表示到达这条路由所指目的地址的代价。度量值数值越小越优先&#xff0c;度量值最小路由将会被添加到路由表中。度量值很多时候被称为开销(Cost)。 路由度量(路由开销 cost)对于同一个路由协议&#xff0c;当到达某目标网段有多条路由供…

SQL Server入门-安装和测试(2008R2版)

环境&#xff1a;win10&#xff0c;SQL Server 2008 R2 因为工作需要用到SQL Server&#xff08;而且要用2008R2版&#xff09;&#xff0c;完全不熟&#xff0c;所以来学习学习。 SQL Server是微软开发的关系型数据库&#xff0c;支持SQL。同时还有微软还开发了自己的T-SQL&am…

Fontconfig head is null, check your fonts or fonts configuration问题解决

报错信息&#xff1a; Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [R equest processing failed: com.alibaba.excel.exception.ExcelGenerateException: java.lang.InternalError: java.lang.reflect.InvocationTargetExcep…

11 类型泛化

11 类型泛化 1、函数模版1.1 前言1.2 函数模版1.3 隐式推断类型实参1.4 函数模板重载1.5 函数模板类型形参的默认类型&#xff08;C11标准&#xff09; 2、类模版2.1 类模板的成员函数延迟实例化2.2 类模板的静态成员2.3 类模板的递归实例化2.4 类模板类型形参缺省值 3、类模板…

小鹏汽车2025冲刺类L4智驾,挑战与机遇并存

随着科技的飞速发展&#xff0c;智能驾驶已成为汽车行业的前沿领域。近日&#xff0c;小鹏汽车在AI DAY上宣布国内首个量产上车的端到端大模型&#xff0c;这一创新举措无疑为智能驾驶的发展注入了新的活力。然而&#xff0c;在迈向2025年实现类L4级智能驾驶的道路上&#xff0…

大前端 业务架构 插件库 设计模式 属性 线程

大前端 业务架构 插件库 适配模式之(多态)协议1对多 抽象工厂模式 观察者模式 外观模式 装饰模式之参考catagory 策略模式 属性

橡胶油封的用途是什么?

橡胶油封的用途是什么? 在机械工程和设备维护领域&#xff0c;橡胶油封发挥着至关重要的作用&#xff0c;确保各部件的耐用性和效率。那么&#xff0c;橡胶油封的具体用途是什么呢?本文将从多角度探讨橡胶油封的应用和优势&#xff0c;突出其在各个工业和汽车领域中的重要性…

QT 中文乱码 以及 tr 的使用

一、关于显示中文 1、网上常规的做法 - 第一步&#xff1a;代码文件选择用utf8编码带bom。QT Creator 文本编辑 行为配置里可以配置 - 第二步&#xff1a;在有中文汉字的代码文件顶部加一行&#xff08;一般是cpp文件&#xff09; #pragma execution_character_set("utf-…

服务器新硬盘分区、格式化和挂载

文章目录 参考文献查看了一下起点现状分区(base) ~ sudo parted /dev/sdcmklabel gpt&#xff08;设置分区类型&#xff09;增加分区 格式化需要先退出quit&#xff08;可以&#xff09;(base) / sudo mkfs.xfs /dev/sdc/sdc1&#xff08;失败&#xff09;sudo mkfs.xfs /dev/s…

通过nginx转发后应用偶发502bad gateway

序言 学习了一些东西&#xff0c;如何才是真正自己能用的呢&#xff1f;好像就是看自己的潜意识的反应&#xff0c;例如解决了一个问题&#xff0c;那么下次再碰到类似的问题&#xff0c;能直接下意识的去找到对应的信息&#xff0c;从而解决&#xff0c;而不是和第一次碰到一样…

softmax的数值溢出问题

softmax是deep learning常用的一个操作&#xff0c;虽然有很多现成的包可以调&#xff0c;但在某些场景下需要自己实现。本文简单探讨一下softmax可能会出现的数值稳定性问题 解决上溢出问题 Softmax ( x i ) exp ⁡ ( x i ) ∑ j 1 N exp ⁡ ( x j ) exp ⁡ ( x i ) / exp…

CRC循环冗余校验

CRC循环冗余校验 循环冗余校验码是一种用在数字网络和存储设备上的差错校验码&#xff0c;可以校验原始数据的偶然差 错。 CRC 计算单元使用固定多项式计算 32 位 CRC 校验码。 1. 硬件CRC 在单片机中&#xff0c;芯片具有专用的CRC计算单元&#xff0c;它是按照32位数据长…

LeetCode 48.旋转图像

1.做题要求: 2.从此题我们可以看出规律为第几行要变为倒数第几列&#xff0c;所以我们最好先把二维数组存入一维数组中&#xff0c;然后先从最后一列遍历&#xff0c;把一维数组里的元素&#xff0c;依次等于遍历的元素即可: void rotate(int** matrix, int matrixSize, int*…

RunMe_Aobut TC103848_UEFIShellFactoryDiagnostics.nsh

:: ***************************************************************************************************************************************************************** :: 20240617 :: 该脚本可以用于BIOS Case TC103848测试,功能包括&#xff1a;在EFIShell环境下运行…

Scala函数

文章目录 一、第1关&#xff1a;方法S 三角形 ​实验代码&#xff1a; 二、第2关&#xff1a;Scala函数以及函数调用实验代码&#xff1a; 一、第1关&#xff1a;方法 任务描述 本关任务&#xff1a;根据三角形的三边长 a、b、c&#xff0c;返回三角形的面积。 任意三角形面积…

外网怎么访问内网?

当我们需要在外网环境下访问内网资源时&#xff0c;常常会面临一些困扰。通过使用一些相关的技术与工具&#xff0c;我们可以轻松地实现这一目标。本文将介绍如何通过【天联】组网产品&#xff0c;解决外网访问内网的问题。 【天联】组网是一款由北京金万维科技有限公司自主研…