roc*_*hus 7 sql postgresql ruby-on-rails
我正在创建一个Rails应用程序,它将取代我的雇主的(非常旧的)遗留订单管理应用程序.新系统的规格之一是订单编号系统保持不变.现在,我们的订单号格式如下:
例如,2014年6月的第一个订单的订货号为2014060001.下一个订单的订货号为2014060002,依此类推.
此订单号需要是Orders表中的主要ID.看来我需要为PostgreSQL设置一个自定义序列来分配主键,但是我可以找到的用于创建自定义序列的唯一文档是非常基本的(如何增加两个而不是一个,等等).如何根据上述日期创建自定义序列?
Pat*_*ick 12
您可以使用以下EXTRACT()函数将手动创建的序列设置为特定值:
setval('my_sequence',
(EXTRACT(YEAR FROM now())::integer * 1000000) +
(EXTRACT(MONTH FROM now())::integer * 10000)
);
Run Code Online (Sandbox Code Playgroud)
输入的下一个订单将采用序列中的下一个值,即YYYYMM0001等.
诀窍是何时更新序列值.您可以在PG内部以硬盘方式执行此操作并BEFORE INSERT在订单表上写入一个触发器,以检查这是否是新月中的第一条记录:
CREATE FUNCTION before_insert_order() RETURNS trigger AS $$
DECLARE
base_val integer;
BEGIN
-- base_val is the minimal value of the sequence for the current month: YYYYMM0000
base_val := (EXTRACT(YEAR FROM now())::integer * 1000000) +
(EXTRACT(MONTH FROM now())::integer * 10000);
-- So if the sequence is less, then update it
IF (currval('my_sequence') < base_val)
setval('my_sequence', base_val);
END IF;
-- Now assign the order id and continue with the insert
NEW.id := nextval('my_sequence');
RETURN NEW;
END; $$ LANGUAGE plpgsql;
CREATE TRIGGER tr_bi_order
BEFORE INSERT ON order_table
FOR EACH ROW EXECUTE PROCEDURE before_insert_order();
Run Code Online (Sandbox Code Playgroud)
为什么这很难?因为您检查每个插入序列的值.如果您每天只有少量插入且系统不是很忙,这是一种可行的方法.
如果你不能省去所有这些CPU周期,你可以安排一个cron作业在每个月的第一天00:00:01运行,以执行PG功能psql来更新序列,然后只使用序列作为新的默认值订单记录(因此不需要触发器).
| 归档时间: |
|
| 查看次数: |
3814 次 |
| 最近记录: |