我正在使用旧版Oracle数据库,该数据库的列包含日期字符串,格式如下:
30-Apr-03
30-Apr-2003
列数据类型为VARCHAR2(12)
(尽管11
就足够了)。这两个表示都可以出现在一个列中。
问题:如何编写CHECK
约束,允许仅列中的这两个日期字符串变体?
答案 0 :(得分:2)
以下是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第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
约束的想法,以便它真正实现目标。