当前位置: 首页 > news >正文

高斯数据库触发器实现流水号的

✅ 一、修改表结构:支持多业务类型

CREATE TABLE serial_number (biz_type TEXT NOT NULL,serial_date DATE NOT NULL,current_no INT NOT NULL,PRIMARY KEY (biz_type, serial_date)
);

✅ 二、生成函数:带业务前缀

CREATE OR REPLACE FUNCTION generate_serial_no(p_biz_type TEXT)
RETURNS TEXT AS $$
DECLAREtoday DATE := CURRENT_DATE;next_no INT;serial TEXT;
BEGIN-- 检查是否已有记录IF EXISTS (SELECT 1 FROM serial_numberWHERE biz_type = p_biz_type AND serial_date = today) THEN-- 更新序号UPDATE serial_numberSET current_no = current_no + 1WHERE biz_type = p_biz_type AND serial_date = todayRETURNING current_no INTO next_no;ELSE-- 插入新记录INSERT INTO serial_number(biz_type, serial_date, current_no)VALUES (p_biz_type, today, 1)RETURNING current_no INTO next_no;END IF;-- 拼接业务前缀 + 日期 + 三位序号serial := UPPER(p_biz_type) || TO_CHAR(today, 'YYYYMMDD') || LPAD(next_no::TEXT, 3, '0');RETURN serial;
END;
$$ LANGUAGE plpgsql;

✅ 三、使用示例

SELECT generate_serial_no('order');
-- 返回:ORDER20250725001SELECT generate_serial_no('invoice');
-- 返回:INVOICE20250725001

✅ 四、可选扩展(说明)

如果你还有这些需求,也可以加上:

扩展功能说明
自定义位数LPAD(..., 3, '0') 改成 LPAD(..., n, '0')
加密或混淆可以在返回值中追加随机字母或哈希
使用事务封装保证生成唯一性,在高并发时推荐加 FOR UPDATE

触发器(Trigger)+ 触发器函数

你是想实现这样一种效果吧:

当你 INSERT 某张业务表(比如订单表)时,流水号字段自动生效,自动生成像 ORDER20250726001 的编号,不需要你手动调用 generate_serial_no()

可以!下面我教你通过 触发器(Trigger)+ 触发器函数 实现这个自动化。


✅ 一、业务表设计(例如订单表)

CREATE TABLE orders (id SERIAL PRIMARY KEY,order_no TEXT,  -- 自动生成的流水号customer_name TEXT,create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

✅ 二、创建触发器函数:自动生成 order_no

CREATE OR REPLACE FUNCTION auto_generate_order_no()
RETURNS TRIGGER AS $$
BEGINIF NEW.order_no IS NULL THENNEW.order_no := generate_serial_no('order');END IF;RETURN NEW;
END;
$$ LANGUAGE plpgsql;

✅ 三、创建触发器

CREATE TRIGGER trg_orders_generate_no
BEFORE INSERT ON orders
FOR EACH ROW
EXECUTE FUNCTION auto_generate_order_no();

✅ 四、插入数据测试

INSERT INTO orders (customer_name) VALUES ('张三');
-- 自动生成 order_no,如:ORDER20250725001INSERT INTO orders (customer_name) VALUES ('李四');
-- 自动生成 order_no,如:ORDER20250725002

✅ 五、如果你有多个表共享流水号逻辑怎么办?

很好,这是实际开发中非常常见的需求。

你有多个业务表(如订单表、发票表、合同表等),每个表都要自动生成类似 ORDER20250726001INVOICE20250726001 的流水号,但又不想为每张表单独写一个触发器函数,那该怎么做?


✅ 目标

  1. 多个表插入时自动生成带前缀的流水号;
  2. 复用同一个触发器函数
  3. 每张表生成自己的前缀流水号(如 orders 表前缀是 ORDER)。

✅ 一、准备工作:映射表名到前缀

我们先建一个映射表,配置表名 → 前缀

CREATE TABLE biz_prefix_map (table_name TEXT PRIMARY KEY,prefix TEXT NOT NULL
);-- 示例数据
INSERT INTO biz_prefix_map (table_name, prefix) VALUES
('orders', 'ORDER'),
('invoices', 'INVOICE'),
('contracts', 'CONTRACT');

✅ 二、共用的触发器函数

这个函数可以被所有业务表共用,自动从映射表中获取前缀:

CREATE OR REPLACE FUNCTION auto_generate_serial_no()
RETURNS TRIGGER AS $$
DECLAREbiz_prefix TEXT;
BEGIN-- 获取当前触发表的业务前缀SELECT prefix INTO biz_prefixFROM biz_prefix_mapWHERE table_name = TG_TABLE_NAME;IF biz_prefix IS NULL THENRAISE EXCEPTION 'No prefix configured for table %', TG_TABLE_NAME;END IF;-- 设置流水号字段(字段名必须统一为 serial_no 或自己统一规则)IF NEW.serial_no IS NULL THENNEW.serial_no := generate_serial_no(biz_prefix);END IF;RETURN NEW;
END;
$$ LANGUAGE plpgsql;

✅ 三、你的业务表结构统一命名(字段统一为 serial_no

例如:

CREATE TABLE orders (id SERIAL PRIMARY KEY,serial_no TEXT,  -- 自动生成的编号customer_name TEXT
);CREATE TABLE invoices (id SERIAL PRIMARY KEY,serial_no TEXT,amount NUMERIC
);

✅ 四、为每个表添加触发器(共用函数)

CREATE TRIGGER trg_orders_serial
BEFORE INSERT ON orders
FOR EACH ROW
EXECUTE FUNCTION auto_generate_serial_no();CREATE TRIGGER trg_invoices_serial
BEFORE INSERT ON invoices
FOR EACH ROW
EXECUTE FUNCTION auto_generate_serial_no();

✅ 五、插入效果

INSERT INTO orders (customer_name) VALUES ('小张');
-- 自动生成 serial_no:ORDER20250725001INSERT INTO invoices (amount) VALUES (300.00);
-- 自动生成 serial_no:INVOICE20250725001

✅ 总结

优点说明
统一管理所有流水号逻辑集中在一张表和一个函数里
易扩展新增业务表只需加一条映射数据和触发器
自动生效所有业务表自动生成唯一编号

http://www.xdnf.cn/news/1188073.html

相关文章:

  • 去中心化时代的通信革命:briefing与cpolar技术融合带来的安全范式革新
  • 【Linux系统】理解硬件 | 引入文件系统
  • 机器学习特征工程:特征选择及在医学影像领域的应用
  • 数字孪生映射探索驱动的具身导航!MorphoNavi:面向对象映射的空地机器人导航
  • 2D游戏背景滚动教程(JavaSwing)
  • 机器学习特征工程详解:特征选择与降维(PCA)
  • 数据赋能(336)——技术平台——智能化运营
  • 2.JVM跨平台原理(字节码机制)
  • Java研学-RabbitMQ(二)
  • C++中new和delete的多重面孔:operator new、new operator与placement new解析
  • 初识java
  • Python 程序设计讲义(20):选择结构程序设计——双分支结构的简化表示(三元运算符)
  • Model Control Protocol 三层架构设计,三种传输方式,完成MCP项目构建实现工具调试,多维度评价指标检测多工具多资源调用的鲁棒性和稳健性
  • java面试题(二)
  • 栈----1.有效的括号
  • 扒网站工具 HTTrack Website Copier
  • 3020雕刻机脱机自定义指令
  • 一些常见的网络攻击方式
  • 疯狂星期四第19天运营日记
  • Java并发编程第十篇(ThreadPoolExecutor线程池组件分析)
  • 锁相环技术简介(面向储能变流器应用)
  • 机器学习(一)KNN,K近邻算法(K-Nearest Neighbors)
  • [硬件电路-85]:一款高集成度热电制冷器(TEC)控制器芯片ADN8835ACPZ
  • 工程师实践出真知
  • 【Spring WebFlux】为什么 Spring 要拥抱响应式
  • java面试题(一)
  • 基于深度学习的图像分类:使用DenseNet实现高效分类
  • 解决 Delete ␍ prettier/prettier问题的方案
  • TwinCAT3编程入门1
  • 理解Spring中的IoC