我正在使用一个遗留的 Oracle 数据库,该数据库的列包含格式如下的日期字符串:
30-Apr-03
30-Apr-2003
列数据类型是VARCHAR2(12)
(尽管11
就足够了)。这两种表示都可以出现在单个列中。
问题:如何编写一个仅CHECK
允许列中的这两个日期字符串变体的约束?
我正在使用一个遗留的 Oracle 数据库,该数据库的列包含格式如下的日期字符串:
30-Apr-03
30-Apr-2003
列数据类型是VARCHAR2(12)
(尽管11
就足够了)。这两种表示都可以出现在单个列中。
问题:如何编写一个仅CHECK
允许列中的这两个日期字符串变体的约束?
这是CHECK
验证表单19-Oct-12
或19-Oct-2012
. 对于具有两位数年份的日期字符串,请使用RegEx为年份添加前缀19
以避免 Oracle 错误ORA-02436 - date or system variable wrongly specified in CHECK constraint
。
ALTER TABLE table1
MODIFY col_date1 CONSTRAINT col_date1_ck
CHECK ((TO_DATE(
REGEXP_REPLACE(col_date1, '^(......-)(..)$', '\119\2'),
'DD-Mon-YYYY') > TO_DATE('31-Dec-1899')));
从长远来看,如果可以接受对模式进行更改,则使用DATE数据类型(11g Release 2 (11.2))会更合适。
更新:不幸的是,这不是一个有效的解决方案。首先,这是这种CHECK
约束按预期工作的情况:
Value: '05/Nov/12'
Result: ORA-02290: check constraint (TABLE1.COL_DATE1_CK) violated
但是,此日期字符串被约束接受:
Value: '05/Nov/2012'
这是不想要的,因为目的是'-'
用作字段分隔符,而不是'/'
. 最后,考虑这个日期字符串及其结果:
Value: '05/Foo/2012'
Result: ORA-01843: not a valid month
在这里,约束也不允许这个值进入受保护的列。但是,结果异常中没有任何迹象表明这是违反约束的。(想要的是ORA-02290
如第一个示例中所示。但是TO_DATE()
返回异常而不是CHECK
返回约束False
。)
替代方案:出于这些原因,我最终决定通过触发器来解决这个问题。但我当然欢迎有关修改此CHECK
约束以使其真正实现目标的想法。