我需要对数据类型有一个CHECK约束,该数据类型的格式必须为010000
到129999
且保留为零,但我不知道如何实现这一点。基本上,很明显,这是一个数字月份。
我尝试过使用numeric(6,0)
和integer
,但我不知道如何使用保留前导零的CHECK。
我也不知道如何使用character varying(6)
更轻松地实现这一点,并且它也不是首选,因为我认为在应用程序层中使用它会更难。
有什么建议吗?我正在使用Postgres。
答案 0 :(得分:1)
三种方式(可能还有更多):
-- (1) use a date type for a date
CREATE TABLE mmyyyy
( id SERIAL NOT NULL PRIMARY KEY
, yyyymm01 DATE NOT NULL CHECK (date_trunc('month', yyyymm01) = yyyymm01)
);
INSERT INTO mmyyyy(yyyymm01) VALUES
('1901-01-01') ,('0001-01-01') ,('2016-02-01') ;
INSERT INTO mmyyyy(yyyymm01) VALUES ('1901-13-01') ; -- should fail
INSERT INTO mmyyyy(yyyymm01) VALUES ('2016-02-13') ; -- should fail
SELECT id, to_char(yyyymm01, 'mmyyyy') AS this FROM mmyyyy ;
-- (2) use a char type and apply the check on the cast_to_int result
CREATE TABLE omg
( id SERIAL NOT NULL PRIMARY KEY
, mmyyyy varchar(6) NOT NULL CHECK (
length(mmyyyy) = 6 AND
left(mmyyyy,2)::integer BETWEEN 1 AND 12)
);
INSERT INTO omg(mmyyyy) VALUES ('011901') ,('010001') ,('022016') ;
INSERT INTO omg(mmyyyy) VALUES ('131901') ; -- should fail
INSERT INTO omg(mmyyyy) VALUES ('002016') ; -- should fail
SELECT id, mmyyyy FROM omg ;
-- (3) use an int type and apply the check to the value/10000
CREATE TABLE wtf
( id SERIAL NOT NULL PRIMARY KEY
, mmyyyy INTEGER NOT NULL CHECK (
mmyyyy/10000 BETWEEN 1 AND 12)
);
INSERT INTO wtf(mmyyyy) VALUES
(11901) ,(10001) ,(22016)
;
INSERT INTO wtf(mmyyyy) VALUES (131901) ; -- should fail
INSERT INTO wtf(mmyyyy) VALUES (2016) ; -- should fail
SELECT id, to_char(mmyyyy, '099999') AS mmyyyy
FROM wtf
;
-- (extra) use an date/char/int type AS the baseclass for a domain(or type):
-- (this can come in handy if the "type" is used in more than one place)
CREATE DOMAIN omgwtf AS
INTEGER CHECK ( value/10000 BETWEEN 1 AND 12)
;
CREATE TABLE tralala
( id SERIAL NOT NULL PRIMARY KEY
, mmyyyy omgwtf NOT NULL
);
INSERT INTO tralala(mmyyyy) VALUES
(11901) ,(10001) ,(22016)
;
INSERT INTO tralala(mmyyyy) VALUES (131901) ; -- should fail
INSERT INTO tralala(mmyyyy) VALUES (2016) ; -- should fail
SELECT id, to_char(mmyyyy, '099999') AS mmyyyy
FROM tralala
;
输出:
CREATE TABLE
INSERT 0 3
ERROR: date/time field value out of range: "1901-13-01"
LINE 1: INSERT INTO mmyyyy(yyyymm01) VALUES ('1901-13-01') ;
^
HINT: Perhaps you need a different "datestyle" setting.
ERROR: new row for relation "mmyyyy" violates check constraint "mmyyyy_yyyymm01_check"
DETAIL: Failing row contains (4, 2016-02-13).
id | this
----+--------
1 | 011901
2 | 010001
3 | 022016
(3 rows)
CREATE TABLE
INSERT 0 3
ERROR: new row for relation "omg" violates check constraint "omg_mmyyyy_check"
DETAIL: Failing row contains (4, 131901).
ERROR: new row for relation "omg" violates check constraint "omg_mmyyyy_check"
DETAIL: Failing row contains (5, 002016).
id | mmyyyy
----+--------
1 | 011901
2 | 010001
3 | 022016
(3 rows)
CREATE TABLE
INSERT 0 3
ERROR: new row for relation "wtf" violates check constraint "wtf_mmyyyy_check"
DETAIL: Failing row contains (4, 131901).
ERROR: new row for relation "wtf" violates check constraint "wtf_mmyyyy_check"
DETAIL: Failing row contains (5, 2016).
id | mmyyyy
----+---------
1 | 011901
2 | 010001
3 | 022016
(3 rows)
CREATE DOMAIN
CREATE TABLE
INSERT 0 3
ERROR: value for domain omgwtf violates check constraint "omgwtf_check"
ERROR: value for domain omgwtf violates check constraint "omgwtf_check"
id | mmyyyy
----+---------
1 | 011901
2 | 010001
3 | 022016
(3 rows)
答案 1 :(得分:-1)
我最终使用yyyymm格式,如@ lad2025所示。