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

Posted

技术标签:

【中文标题】postgresql中的自定义自动增量字段(发票/订单号)【英文标题】:Custom auto-increment field in postgresql (Invoice/Order No.) 【发布时间】:2013-05-12 00:38:19 【问题描述】:

基线要求是按以下格式创建订单号:

(M)M-SSS

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

使用 TRIGGER 我希望自动增量和插入透明地工作。

不幸的是,我已经很久没有接触存储过程了,这是我第一次涉足 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 字段一样。

【问题讨论】:

【参考方案1】:

你在寻找这样的东西吗?

-- 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

【讨论】:

@EvanPlaice 查看更新的答案。查询的第一个版本建立在假设月份部分是固定的两个字符字符串 MM 的基础上。 @EvanPlaice 这有点傻。这是使用字段名称order_number 的sqlfiddle。这意味着您的代码中有一些拼写错误。 我是个笨蛋,我正在使用 pgadmin 来检查代码,并且没有将 UI 输出拖到右侧足以看到完整的结果。 不管怎样,有趣的代码块。使用 coalesce 将查询的 null 结果更改为默认值非常简洁。 最后一件事,是所有必要的显式转换;或者这只是一个好习惯。我正在使用 psql 9.2,它似乎可以毫无问题地处理隐式转换。

以上是关于postgresql中的自定义自动增量字段(发票/订单号)的主要内容,如果未能解决你的问题,请参考以下文章

在 postgresql 中重置自动增量计数器

如何设计Sql数据库中的字段为自动填充数据并自动加1的自增量

从 postgresql 字段中删除自动增量

使用mybatis中的自定义TypeHandler处理PostgreSQL中的Json类型字段

如何在postgresql中设置与id不同的自动增量字段

每组值的自定义序列/自动增量