是否可以在Postgres(9.0)中声明一个serial
字段,该字段将根据模式递增?
例如:
Pattern: YYYY-XXXXX
where YYYY is a year, and XXXXX increments from 00000 - 99999.
或者我应该使用触发器?
编辑:我更喜欢根据服务器日期自动确定年份。 XXXXX
部分每年以00000开头,并且“重置”为00000,然后在修改年份部分时再次增加到99999。
答案 0 :(得分:2)
我会为每年创建一个单独的SEQUENCE
,以便每个序列跟踪一年 - 即使在该年结束之后,您是否需要在该年后使用更多唯一ID。
此功能 all :
通过评论中@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()
。
请注意,你不能同时拥有overloaded function没有参数(就像我之前的例子一样),或者Postgres不会知道在绝望中挑选和抛出异常。
在表定义中将此函数用作DEFAULT
值:
CREATE TABLE tbl (id text DEFAULT f_year_id(), ...)
或者您可以获得您选择的一年的下一个值:
SELECT f_year_id('2012');
在Postgres 9.1中测试过。也应该在v9.0或v9.2中工作。
要了解这里发生了什么,请阅读手册中的这些章节:
CREATE FUNCTION
CREATE SEQUENCE
39.6.3. Simple Loops
39.5.4. Executing Dynamic Commands
39.6.6. Trapping Errors
Appendix A. PostgreSQL Error Codes
Table 9-22. Template Pattern Modifiers for Date/Time Formatting
答案 1 :(得分:1)
您可以创建一个将形成此值的函数(YYYY-XXXXX)并将此函数设置为列的默认值。
详情here。