我正在创建一个Customer表,我希望其中一个属性是信用卡的到期日。我希望格式为'Month Year'。我应该使用什么数据类型?我想使用日期,但格式是年/月/日。有没有其他方法可以将格式限制为只有月份和年份?
答案 0 :(得分:4)
您可以将日期约束为该月的第一天:
create table customer (
cc_expire date check (cc_expire = date_trunc('month', cc_expire))
);
现在失败了:
insert into customer (cc_expire) values ('2014-12-02');
ERROR: new row for relation "customer" violates check constraint "customer_cc_expire_check"
DETAIL: Failing row contains (2014-12-02).
这有效:
insert into customer (cc_expire) values ('2014-12-01');
INSERT 0 1
但输入的日期并不重要。您只会查看月份:
select
date_trunc('month', cc_expire) > current_date as valid
from customer;
valid
-------
t
分别提取年份和月份:
select extract(year from cc_expire) "year", extract(month from cc_expire) "month"
from customer
;
year | month
------+-------
2014 | 12
或连接:
select to_char(cc_expire, 'YYYYMM') "month"
from customer
;
month
--------
201412
答案 1 :(得分:0)
使用
以下代码假定为两位数年份,这是与我的所有信用卡相匹配的表格。首先,让我们创建一个有效的到期日期表。
create table valid_expiration_dates (
exp_date char(5) primary key
);
现在让我们来填充它。此代码仅适用于2013年。您可以通过更改开始日期(当前为“2013-01-01”)和月份“数量”(目前为11个月,可让您通过添加来自2013年全部)来轻松调整范围到开始日期0到11个月。)
with all_months as (
select '2013-01-01'::date + (n || ' months')::interval months
from generate_series(0, 11) n
)
insert into valid_expiration_dates
select to_char(months, 'MM') || '/' || to_char(months, 'YY') exp_date
from all_months;
现在,在数据表中,创建一个char(5)列,并将其中的外键引用设置为valid_expiration_dates.exp_date。
当你忙于这个时,请认真思考“exp_month”对于该列是否比“exp_date”更好。 (我想会的。)
答案 2 :(得分:0)
作为另一个想法,您可以使用int []:
基本上创建一些简短的实用程序来为您执行此操作CREATE OR REPLACE FUNCTION exp_valid(int[]) returns bool LANGUAGE SQL IMMUTABLE as
$$
SELECT $1[1] <= 12 AND (select count(*) = 2 FROM unnest($1));
$$;
CREATE OR REPLACE FUNCTION first_invalid_day(int[]) RETURNS date LANGUAGE SQL IMMUTABLE AS
$$
SELECT (to_date($1[2]::text || $1[1]::text, CASE WHEN $1[2] < 100 THEN 'YYMM' ELSE 'YYYYMM' END) + '1 month'::interval)::date;
$$;
这些工作:
postgres=# select exp_valid('{04,13}');
exp_valid
-----------
t
(1 row)
postgres=# select exp_valid('{13,04}');
exp_valid
-----------
f
(1 row)
postgres=# select exp_valid('{04,13,12}');
exp_valid
-----------
f
(1 row)
然后我们可以将这些转换为日期:
postgres=# select first_invalid_day('{04,13}');
first_invalid_day
-------------------
2013-05-01
(1 row)
这种数组的使用不违反任何规范化规则,因为数组作为一个整体代表其域中的单个值。我们存储两个表示单个日期的整数。 '{12,2}'是2002年12月,而'{2,12}'是2012年2月。每个代表域的单个值,因此是完全原子的。