次のように書式設定された日付文字列を含む列を持つレガシー Oracle データベースを使用しています。
30-Apr-03
30-Apr-2003
列のデータ型はVARCHAR2(12)
(11
十分ですが) です。これらの表現はどちらも 1 つの列に表示できます。
質問:列でこれら 2 つの日付文字列バリアントのみCHECK
を許可する制約を作成するにはどうすればよいですか?
次のように書式設定された日付文字列を含む列を持つレガシー Oracle データベースを使用しています。
30-Apr-03
30-Apr-2003
列のデータ型はVARCHAR2(12)
(11
十分ですが) です。これらの表現はどちらも 1 つの列に表示できます。
質問:列でこれら 2 つの日付文字列バリアントのみCHECK
を許可する制約を作成するにはどうすればよいですか?
またはCHECK
の形式の日付文字列を検証するための制約を次に示します。年が 2 桁の日付文字列の場合は、RegExを使用して年の前に を付けて、Oracle エラーを回避します。19-Oct-12
19-Oct-2012
19
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
False
代替案:これらの理由から、私は最終的にトリガーを介してこの問題を解決することにしました。CHECK
しかし、この制約を真に目的を達成できるように修正するアイデアは歓迎します。