我需要對數據類型具有CHECK約束,該數據類型必須具有010000
到129999
的格式,並保留零,但我不知道如何實現這個。基本上,顯而易見,這是一個數字的月份。需要對SQL中的數字應用CHECK約束和長度檢查
我試過使用numeric(6,0)
和integer
,但我不知道如何使用保留前導零的CHECK。
我也不知道如何使用character varying(6)
更容易實現這一點,也不是首選,因爲我認爲在應用程序層使用它會更困難。
有什麼建議嗎?我正在使用Postgres。
我需要對數據類型具有CHECK約束,該數據類型必須具有010000
到129999
的格式,並保留零,但我不知道如何實現這個。基本上,顯而易見,這是一個數字的月份。需要對SQL中的數字應用CHECK約束和長度檢查
我試過使用numeric(6,0)
和integer
,但我不知道如何使用保留前導零的CHECK。
我也不知道如何使用character varying(6)
更容易實現這一點,也不是首選,因爲我認爲在應用程序層使用它會更困難。
有什麼建議嗎?我正在使用Postgres。
我結束了使用YYYYMM格式,由@ lad2025的建議。
三種方法(可能還有更多):
-- (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)
無法創建新表格;該字段應該是現有字段的一部分。無法爲此字段創建單獨的Java類。另外,(3)不適用,因爲應保留0。 – cst1992
你的'numeric(6,0)'是(雖然是一個不好的選擇),與我的整數版本非常相似。 Java是無關緊要的,儘管它似乎允許強打字 – wildplasser
如果你想存儲月份和年份,我寧願去兩個整數列。 –
我問過那個,但沒有辦法。 – cst1992
'yyyymm'格式('201512,201601')怎麼樣? – lad2025