两个日期字符串变量的Oracle CHECK约束

时间:2012-10-19 14:44:27

标签: regex oracle validation date check-constraints

我正在使用旧版Oracle数据库,该数据库的列包含日期字符串,格式如下:

30-Apr-03

30-Apr-2003

列数据类型为VARCHAR2(12)(尽管11就足够了)。这两个表示都可以出现在一个列中。

问题:如何编写CHECK约束,允许列中的这两个日期字符串变体?

1 个答案:

答案 0 :(得分:2)

以下是CHECK约束,用于验证表单19-Oct-1219-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第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的{​​{1}}约束。)

替代方案:由于这些原因,我最终决定通过触发器解决此问题。但我当然欢迎有关修改这个False约束的想法,以便它真正实现目标。