postgresql 触发器如何生成递增序列号,从1开始,并且每天重置

大家好,我是三叔,许久不见,这期给大家介绍一下笔者在开发中遇到的业务处理:pgsql 创建触发器生成每日递增序列,并且第二天重置,根据不同的用户进行不同的控制。

1.创建生成递增序列的 table 表

-- 创建user_sequences表,用于保存生成的序列号
CREATE TABLE user_sequences 
(
    id                        serial,
    user_name                 varchar(255) NULL,                           -- 区分不同用户(可根据不同业务组装key)
    increment_value           int4 NULL,                                   -- 递增序列号
    last_increment_date       timestamp NULL,                              -- 触发器参数时间
	description				  varchar(255) NULL,						   -- 描述
    tenant_id                 varchar(32) NULL,                            -- 租户ID
    create_user               varchar(32) NULL,                            -- 创建人ID
    create_time               timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
    update_user               varchar(32) NULL,                            -- 最后修改人ID
    update_time               timestamp NULL DEFAULT CURRENT_TIMESTAMP,    -- 更新时间
    CONSTRAINT user_sequences_pk PRIMARY KEY (id)
);

2.创建一个触发器函数

要创建一个触发器,你需要:
1、使用 create function 语句创建一个触发器函数
2、使用 create trigger 语句将触发器函数绑定到数据表
3、创建触发器函数语法:
触发器函数与普通函数类似,不同之处在于触发器不需要任何参数,并且触发器函数需要返回trigger类型值

-- 创建触发器函数
CREATE OR REPLACE FUNCTION insert_increment_value_if_not_exists()
RETURNS TRIGGER AS $$
BEGIN
  -- 检查 user_sequences 表中是否存在对应的 user_name
  IF NOT EXISTS (
    SELECT 1 FROM user_sequences WHERE user_name = NEW.user_name
  ) THEN
    -- 在 user_sequences 表中插入新的记录
    RETURN NEW;
  else 	 
	UPDATE user_sequences
    SET increment_value = increment_value + 1
    WHERE user_name = NEW.user_name
	; 
  END IF;
  RETURN null;
END;
$$ LANGUAGE plpgsql;
上述部分语法解释
NEW:该变量为 INSERT/UPDATE 操作触发的行级触发器中存储新的数据行

3.创建触发器

-- 这里介绍一下创建触发器语法(如下简单语法):
create trigger trigger_name
    {before | after | instead of} event1 or event2...
    on table_name
    {for each row | for each statement}
    execute procedure trigger_function;

event1: 事件可以是:insert, update, delete, truncate
before: 表示定义触发器在事件之前
after:   表示定义触发器在事件之后
intead of:   表示仅用于视图的insert, update, delete
for each row:表示行级触发器
for each statement:表示语级触发器

实际业务逻辑如下:笔者在插入表数据的时候触发执行器执行begin -》end 的 sql 逻辑,这样,我就能在每天对不同的用户,生成一个从1开始的递增序列,每次相同用户同一天访问一次,序列递增加1:

CREATE TRIGGER insert_increment_value_trigger
BEFORE INSERT ON user_sequences
FOR EACH ROW
EXECUTE FUNCTION insert_increment_value_if_not_exists();

4.业务处理逻辑

大家可以看到,在创建触发器的时候,有这么一句语法:BEFORE INSERT ON user_sequences,这句话是什么意思呢?
根据上面的触发器语法介绍可以知道,在每次执行 insert 语句之前,会执行触发器里面的语法。

@Service
public class xxxCommon {

    @Autowired
    private TableMapper mapper;

    @Transactional(rollbackFor = Exception.class)
    public String getSequencesNum(String userName) {
    // 需要注意的是这里的userName需要保证唯一,可以拼接时间yyyyMMdd,这样可以保证每天获取新的递增序列
    // 第二种方法,就是在笔者的基础上,添加时间的判断条件,判断上一次修改或生成数据的时间是否不等于当前时间,如果是的,则重新从1开始递增
        UserSequencesVO vo = new UserSequencesVO();
        assembleParam(vo);
        vo.setIncrementValue(1);
        vo.setUserName(userName);
        // 触发器触发条件,insert 语句进行触发,这里我在xml里面写了一条新增的sql语句,从而触发触发器
        mapper.insertTriger(vo);
        // 这里获取数据库返回的序列号,
        UserSequencesVO sequencesVO = UserSequencesMapper.selectByUserName(userName);
        // 根据自己的业务组装返回值
 		return sequencesVO.getIncrementValue();
    }

    private void assembleParam(UserSequencesVO vo) {
        vo.setDescription("获取当前key的递增序列");
        vo.setTenantId(userUtil.getTenantId());
        vo.setLastIncrementDate(LocalDateTime.now());
        vo.setCreateTime(LocalDateTime.now());
        vo.setCreateUser(userUtil.getId());
        vo.setTenantId(userUtil.getTenantId());
        vo.setUpdateTime(LocalDateTime.now());
        vo.setUpdateUser(userUtil.getTenantId());
    }
}

业务处理

在拿到递增的序列号之后,就可以对序列号进行一系列的组装操作,这样,根据不同的用户,互不影响,获取从 1 开始递增的序列号,并且第二天重置

结果如下:

笔者成功获取到每天操作文档的次数:
在这里插入图片描述

最后:如何删除触发器

DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]

参数说明:

IF EXISTS:如果该触发器不存在
name:要移除的刚刚定义的触发器的名称
table_name:定义了该触发器的表的名称
CASCADE:自动删除依赖于该触发器的对象,然后删除所有 依赖于那些对象的对象
RESTRICT:如果有任何对象依赖于该触发器,则拒绝删除它,这是默认值

-- 示例
DROP TRIGGER insert_increment_value_trigger ON user_sequences;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线程池与工厂模式

目录 ♫什么是线程池 ♫线程池的优点 ♫工厂模式 ♫工厂模式的意义 ♫线程池的使用 ♫线程池常见的创建方法 ♫ThreadPoolExecutor ♫实现一个线程池 ♫什么是线程池 线程池是一种管理和复用线程的技术,它在应用程序启动时预先创建一组线程,并将它…

uniapp写一个计算器用于记账(微信小程序,APP)

提要:自己用uniapp写了一个记账小程序(目前是小程序),写到计算器部分,在网上找了别人写的计算器,大多数逻辑都是最简单的,都不能满足一个记账计算器的基本逻辑。与其在网上找来找去,…

由CAB/PAB展开的一些思考

又到了一月保底一篇订阅号文章的时候,上周受到Oracle邀请,参加了在上海Oracle办公室举行的CAB(The 13th Oracle China Customer Advisory Board Metting)/ PAB(The 3th Oracle China Partner Advisory Board Metting&…

信息论基础知识1

1.1 自信息定义:把某个消息出现的不确定性大小,用这个消息出现的概率的对数表示: I(X)-logp(x) 1.2 在任何一个信息流通的系统中,都有一个发出信息的发送端(信源),有一个接收信息的接收端…

cmake find_package、引用GDAL 初步学习

上次的源码的CMakeLists.txt文件里有 find_package(GDAL REQUIRED) 这句; 从字面意思看此源码需要GDAL库; 查了一下,find_package 指令的基本功能是查找第三方库,并返回其细节; 我当前GDAL安装在D:\GDAL; 先把它的CMakeLists.txt重命名为别的,不使用; 新建一个C…

多线程基础

1. 线程创建的几种方式 2. 锁的类型 在学习JUC之前,加锁、等待、唤醒 分别使用的是 (synchronized、lock)、wait、notify在学习JUC开始,学会使用lock接口的其他实现类来进行上述操作,比如 ReentrantLock 3. 线程池 …

哪里能找到可以学习的前端实战项目?

前言 下面是我整理的一些关于GitHub上的前端相关的项目,希望对你有所帮助,整理不易,可以的话不要吝啬你的点赞喜欢收藏哈~ 废话少说,我们直接进入正题——> 实用工具向 1.Echarts Star:55.6k Echarts提供了大量…

从零开始的目标检测和关键点检测(二):训练一个Glue的RTMDet模型

从零开始的目标检测和关键点检测(二):训练一个Glue的RTMDet模型 一、config文件解读二、开始训练三、数据集分析四、ncnn部署 从零开始的目标检测和关键点检测(一):用labelme标注数据集 从零开始的目标检测…

Spring、SpringMVC、Mybatis

一.Spring基础 1.Spring 框架是什么 Spring 是一款开源的轻量级 Java 开发框架,我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,例如,Spring core、Spring JDBC、Spring MVC 等,使用这些模块可…

python 数据挖掘库orange3 介绍

orange3 是一个非常适合初学者的data mining library. 它让使用者通过拖拽内置的组件来形成工作流。让你不需要写任何代码就可以体验到数据挖掘和可视化的魅力。 它的桌面如下,这里我创建了 3 个节点,分别是数据集、小提琴图,散点图 其中 …

误删的文件恢复了成乱码 误删的文件恢复了成乱码怎么调整

电脑系统:Windows11 电脑型号:惠普 软件版本:EasyRcovery14 关于电脑,我们可以说是非常熟悉,并熟练掌握了对电脑的最基本操作,比如复制、粘贴、新建、删除文件。但我们真的很懂它吗?比如误删…

SAP SD 定价 删除不满足条件的的条件类型

项目上的需求:当销售订单行项目类别满足条件时,根据配置表,删除不满足条件的的条件类型。 直接上增强点,bapi也能跑到这个位置。

vite安装Tailwind CSS

安装 - Tailwind CSS 中文网 (nodejs.cn) 这是官网,平常我练习一般会用vite脚手架 我们选择这个vite模块 可选择React和Vue版本的,这里选择react的按照操作,没问题的话就要出问题了 1、在npm run dev的时候我是出现了这么个问题&#xff0c…

XML External Entity-XXE-XML实体注入

XML 实体? XML 实体允许定义标签,在解析 XML 文档时这些标签将被内容替换。一般来说,实体分为三种类型: 内部实体 外部实体 参数实体。 必须在文档类型定义(DTD)中创建实体 一旦 XML 文档被解析器处理,它将js用定义的常量“Jo Smith”替换定义的实体。正如您所看到…

React Hooks的使用

目录 1.React Hooks使用注意事项 1.useState Hook: 2.useEffect Hook: 3.其他常用Hooks: 2.使用React Hooks需要遵循 1.安装React: 2.导入所需的Hooks: 3.使用Hooks创建组件: 4.在应用中使用组件&…

Pytorch从零开始实战08

Pytorch从零开始实战——YOLOv5-C3模块实现 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——YOLOv5-C3模块实现环境准备数据集模型选择开始训练可视化模型预测总结 环境准备 本文基于Jupyter notebook,使用Python3.8&#xff0c…

在Node.js中,什么是中间件(middleware)?它们的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

NodeJS 安装及环境配置

下载地址:https://nodejs.org/zh-cn/download/ 安装 NodeJS 根据自己电脑系统及位数选择,一般都选择 windows 64位 .msi 格式安装包。 所用命令: node -v npm -v PS:如果以上两条命令都能执行成功,表示安装完成&#…

虹科荣誉 | 喜讯!虹科成功入选“广州首届百家新锐企业”!!

文章来源:虹科品牌部 阅读原文:虹科荣誉 | 喜讯!虹科成功入选“广州首届百家新锐企业”!! 近日,由中共广州市委统战部、广州市工商业联合会、广州市工业和信息化局、广州市人民政府国有资产监督管理委员会…