0

次のように書式設定された日付文字列を含む列を持つレガシー Oracle データベースを使用しています。

30-Apr-03

30-Apr-2003

列のデータ型はVARCHAR2(12)(11十分ですが) です。これらの表現はどちらも 1 つの列に表示できます。

質問:列でこれら 2 つの日付文字列バリアントのみCHECKを許可する制約を作成するにはどうすればよいですか?

4

1 に答える 1

2

またはCHECKの形式の日付文字列を検証するための制約を次に示します。年が 2 桁の日付文字列の場合は、RegExを使用して年の前に を付けて、Oracle エラーを回避します。19-Oct-1219-Oct-201219ORA-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()が を返すのではなく、例外を返しています。)CHECKFalse

代替案:これらの理由から、私は最終的にトリガーを介してこの問題を解決することにしました。CHECKしかし、この制約を真に目的を達成できるように修正するアイデアは歓迎します。

于 2012-10-19T14:46:25.723 に答える