我正在嘗試在 oracle 中創建下面的這個表,但我想向 datexp(日期格式 'MM/YYYY')屬性添加一個約束,但遺憾的是我的嘗試都沒有正確作業:
create table carte
(
idcarte char(5) primary key,
typec varchar(20)
check(typec in ('E-dinars smart', 'E-dinars universel', 'visa electron', 'visa international', 'mastercard international')),
datexp varchar(9) ,
numerocarte number(20),
signaturecvv2 number(3)
);
我試過:
datexp varchar(9) check(to_date(datexp, 'MM/YYYY')),
datexp varchar(9) check(date_exp = to_date(datexp, 'MM/YYYY')),
uj5u.com熱心網友回復:
在我看來,那是非常錯誤的。永遠不要將日期存盤為字串。從來沒有。它很容易出錯,您不應該浪費時間弄清楚如何創建約束以防止用戶輸入無效日期——讓資料庫來處理。如何?只需設定該DATE列的資料型別即可。
此外,我建議您為以下物件創建參照完整性約束carte types:
SQL> CREATE TABLE carte_type
2 (
3 typec NUMBER CONSTRAINT pk_cartyp PRIMARY KEY,
4 name VARCHAR2 (50) NOT NULL
5 );
Table created.
SQL> CREATE TABLE carte
2 (
3 idcarte CHAR (5) PRIMARY KEY,
4 typec NUMBER CONSTRAINT fk_cart_typ REFERENCES carte_type (typec),
5 datexp DATE,
6 numerocarte NUMBER (20),
7 signaturecvv2 NUMBER (3)
8 );
Table created.
SQL>
如果您擔心日期格式 ( mm/yyyy),請不要擔心 - 輸入屬于該月/年的任何日期,然后 - 在向最終用戶展示該資訊時 - 將所需的格式掩碼應用于to_char功能,例如
select to_char(datexp, 'mm/yyyy') as datexp
from ...
您是否會輸入例如 08/12/2021 (dd/mm/yyyy) 或 23/12/2021 并不重要 - 它們都在 12/2021。
或者,如果您使用的是 GUI 工具(或報告生成器),它已經提供了格式掩碼屬性,因此請使用它。
uj5u.com熱心網友回復:
您應該將日期值存盤為 aDATE并且可以使用檢查約束將其限制為月初的值。您甚至可以添加一個虛擬列以生成DATEXP所需的格式:
CREATE TABLE carte(
idcarte VARCHAR2(5)
CONSTRAINT carte__idcarte__pk PRIMARY KEY,
typec VARCHAR2(20)
CONSTRAINT carte__typec__chk CHECK(
typec in(
'E-dinars smart',
'E-dinars universel',
'visa electron',
'visa international',
'mastercard international'
)
),
datexp DATE
CONSTRAINT carte__datexp__chk CHECK(datexp = TRUNC(datexp, 'MM')),
formatted_datexp
VARCHAR2(7)
GENERATED ALWAYS AS (TO_CHAR(datexp, 'MM/YYYY')),
numerocarte NUMBER(20),
signaturecvv2 NUMBER(3)
);
但是,如果您有正當的商業理由將其存盤為字串(您可能沒有,即使您認為這樣做),從 Oracle 12 開始,您可以嘗試轉換為日期并DEFAULT NULL ON CONVERSION ERROR在檢查約束中使用精確的格式模型:
CREATE TABLE carte(
idcarte VARCHAR2(5)
CONSTRAINT carte__idcarte__pk PRIMARY KEY,
typec VARCHAR2(20)
CONSTRAINT carte__typec__chk CHECK(
typec in(
'E-dinars smart',
'E-dinars universel',
'visa electron',
'visa international',
'mastercard international'
)
),
datexp VARCHAR2(7)
CONSTRAINT carte__datexp__chk CHECK(
TO_DATE(datexp DEFAULT NULL ON CONVERSION ERROR, 'FXMM/YYYY')
IS NOT NULL
),
numerocarte NUMBER(20),
signaturecvv2 NUMBER(3)
);
(注意:在早期版本中,您可以洗掉DEFAULT NULL ON CONVERSION ERROR并且約束仍將被檢查,但它將失敗并出現與決議日期相關的例外,而不是約束失敗導致的更具描述性的錯誤。)
db<>在這里擺弄
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/384988.html
上一篇:如何在javascript中將日期字串從'dd//mm/yy'轉換為'mm/dd/yy'?
下一篇:如何防止編輯excel檔案?
