1

是否可以serial在 Postgres (9.0) 中声明一个将根据模式递增的字段?

例如:

 Pattern: YYYY-XXXXX
 where YYYY is a year, and XXXXX increments from 00000 - 99999.

还是我应该只使用触发器?

编辑:我更喜欢根据服务器日期自动确定年份。该XXXXX部分确实从每年的 00000 开始,并“重置”为 00000,然后在修改年份部分时再次增加到 99999。

4

2 回答 2

2

我会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。日期/时间格式的模板模式修饰符

于 2013-01-11T03:30:12.120 回答
1

您可以创建一个将形成此值 (YYYY-XXXXX) 的函数并将此函数设置为列的默认值。

详情在这里

于 2013-01-10T12:31:40.860 回答