是否可以serial
在 Postgres (9.0) 中声明一个将根据模式递增的字段?
例如:
Pattern: YYYY-XXXXX
where YYYY is a year, and XXXXX increments from 00000 - 99999.
还是我应该只使用触发器?
编辑:我更喜欢根据服务器日期自动确定年份。该XXXXX
部分确实从每年的 00000 开始,并“重置”为 00000,然后在修改年份部分时再次增加到 99999。
是否可以serial
在 Postgres (9.0) 中声明一个将根据模式递增的字段?
例如:
Pattern: YYYY-XXXXX
where YYYY is a year, and XXXXX increments from 00000 - 99999.
还是我应该只使用触发器?
编辑:我更喜欢根据服务器日期自动确定年份。该XXXXX
部分确实从每年的 00000 开始,并“重置”为 00000,然后在修改年份部分时再次增加到 99999。
我会SEQUENCE
为每一年创建一个单独的序列,这样每个序列都会跟踪一年——即使在那一年结束之后,如果你以后需要更多唯一的 ID。
这个功能可以做到这一切:通过评论中@Igor和@Clodoaldo
的输入进行了改进。
CREATE OR REPLACE FUNCTION f_year_id(y text = to_char(now(), 'YYYY'))
RETURNS text AS
$func$
BEGIN
LOOP
BEGIN
RETURN y ||'-'|| to_char(nextval('year_'|| y ||'_seq'), 'FM00000');
EXCEPTION WHEN undefined_table THEN -- error code 42P01
EXECUTE 'CREATE SEQUENCE year_' || y || '_seq MINVALUE 0 START 0';
END;
END LOOP;
END
$func$ LANGUAGE plpgsql VOLATILE;
称呼:
SELECT f_year_id();
回报:
2013-00000
基本上这会返回text
您请求的模式。自动为当年量身定做。如果名称序列year_<year>_seq
尚不存在,则会自动创建nextval()
并重试。
请注意,您不能同时拥有没有参数的重载函数(就像我之前的示例一样),否则 Postgres 将不知道该选择哪个并在绝望中抛出异常。
将此函数用作DEFAULT
表定义中的值:
CREATE TABLE tbl (id text DEFAULT f_year_id(), ...)
或者,您可以获得您选择的一年的下一个值:
SELECT f_year_id('2012');
在 Postgres 9.1 中测试。也应该在 v9.0 或 v9.2 中工作。
要了解这里发生了什么,请阅读手册中的这些章节:
创建函数
创建序列
39.6.3。简单循环
39.5.4。执行动态命令
39.6.6。捕获错误
附录 A. PostgreSQL 错误代码
表 9-22。日期/时间格式的模板模式修饰符
您可以创建一个将形成此值 (YYYY-XXXXX) 的函数并将此函数设置为列的默认值。
详情在这里。