postgresql - postgresql中的自定义自增字段(发票/订单号)

标签 postgresql stored-procedures triggers auto-increment

基本要求是创建以下格式的订单号:

(M)M-SSS

其中 MM 代表当前月份,SSSS 代表该月的订单顺序。例如,1-002 代表一月份提交的第二个订单。

使用触发器,我希望自动增量和插入能够透明地工作。

不幸的是,我已经很久没有接触过存储过程了,这是我第一次接触 postgresql。任何指向正确方向的帮助将不胜感激。

更新:这是使用@peterm代码的最终实现

-- The trigger
CREATE TRIGGER add_order_number 
   BEFORE INSERT ON orders FOR EACH ROW
   EXECUTE PROCEDURE order_number_update();

-- The trigger function
CREATE FUNCTION order_number_update() RETURNS TRIGGER AS $$
DECLARE
    next_order TEXT;
BEGIN
    -- get the next order number
    SELECT INTO next_order CONCAT(CAST(DATE_PART('MONTH', CURRENT_DATE) AS VARCHAR(2)),
       '-', 
       LPAD(CAST(COALESCE(CAST(RIGHT(MAX(order_number), 3) AS INT), 0) + 1 AS VARCHAR(3)), 3, '0'))
    FROM orders
    WHERE CAST(LEFT(order_number, STRPOS(order_number, '-') - 1) AS INT) = DATE_PART('MONTH', CURRENT_DATE);

    -- update the field
    NEW.order_number = next_order;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

注意:通过将更新添加为 BEFORE INSERT 触发器,它会以完全透明且可预测的方式运行,就像普通的 SERIAL 或 BIGSERIAL 字段一样。

最佳答案

您正在寻找这样的东西吗?

-- Next No calculated for current month
SELECT CONCAT(CAST(DATE_PART('MONTH', CURRENT_DATE) AS VARCHAR(2)),
       '-', 
       LPAD(CAST(COALESCE(CAST(RIGHT(MAX(order_no), 4) AS INT), 0) + 1 AS VARCHAR(4)), 4, '0')) next_no
  FROM orders
 WHERE CAST(LEFT(order_no, STRPOS(order_no, '-') - 1) AS INT) = DATE_PART('MONTH', CURRENT_DATE)
;

输出:

| NEXT_NO |
-----------
|  5-0001 |

假设有一条order_no = '1-0001'的记录

-- Next No for January
SELECT CONCAT(CAST(DATE_PART('MONTH', DATE '2013-01-01') AS VARCHAR(2)),
       '-', 
       LPAD(CAST(COALESCE(CAST(RIGHT(MAX(order_no), 4) AS INT), 0) + 1 AS VARCHAR(4)), 4, '0')) next_no
  FROM orders
 WHERE CAST(LEFT(order_no, STRPOS(order_no, '-') - 1) AS INT) = DATE_PART('MONTH', DATE '2013-01-01')
;

输出:

| NEXT_NO |
-----------
|  1-0002 |

<强> SQLFiddle

关于postgresql - postgresql中的自定义自增字段(发票/订单号),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16598959/

相关文章:

将 Bean 列表传递给 Oracle 存储过程的 Java 程序 - 一次性传递整个列表,而不是一个接一个地附加对象

mysql - 用于计算总和的存储过程 - MySQL 5

MySQL - 可以调用函数来执行触发器操作吗?

postgresql - 使用 postgres uuid_generate_v4 时有很多重复值

MySQL 存储过程声明子查询返回多于 1 行

java - 如何使用 Java 和 PostgreSQL 执行\d表名

php - 如何捕获执行的数据库触发器的通知?

google-apps-script - 对于因触发器是由现已禁用的 Google Workplace 用户创建而被禁用的问题,有什么好的解决方法吗?

django - Celery 无法从 Docker 容器内连接到本地 PostgreSQL

sql - PostgreSQL : CAST column only if exists