2012-10-19 7 views
0

Je travaille avec un héritage base de données Oracle qui a des colonnes contenant des chaînes de date formatée comme suit:Oracle contrainte CHECK sur deux Date de chaîne Variantes

30-Apr-03 

30-Apr-2003 

Le type de données de la colonne est VARCHAR2(12) (bien que 11 suffirait). Ces deux représentations peuvent apparaître dans une seule colonne.

Question: Comment puis-je écrire une contrainte CHECK qui permet seulement ces deux variantes de chaîne de date dans une colonne?

Répondre

2

Voici une contrainte CHECK pour valider les chaînes de date du formulaire 19-Oct-12 ou 19-Oct-2012. Dans le cas des chaînes de date avec une année à deux chiffres, utilisez un RegEx pour préfixer l'année avec 19 pour éviter l'erreur 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'))); 

plus long terme, s'il est acceptable d'apporter des modifications au schéma, en utilisant le type de données DATE (11g Release 2 (11.2)) serait plus approprié.


MISE À JOUR: Malheureusement, ce n'est pas une solution efficace. Tout d'abord, voici une situation où cette CHECK contrainte fonctionne comme prévu:

Value: '05/Nov/12' 
Result: ORA-02290: check constraint (TABLE1.COL_DATE1_CK) violated 

Cependant, cette chaîne de date est acceptée par la contrainte:

Value: '05/Nov/2012' 

Ce n'a pas été cherché puisque l'intention est d'utiliser '-' en tant que séparateur de champ, pas '/'. Enfin, pensez à cette chaîne de date et son résultat:

Value: '05/Foo/2012' 
Result: ORA-01843: not a valid month 

Ici aussi, la contrainte ne permettra pas à cette valeur dans la colonne protégée. Cependant, il n'y a aucune indication dans l'exception résultante qu'il s'agissait d'une violation de contrainte. (Ce qui est recherché est ORA-02290 comme le montre le premier exemple Mais TO_DATE() retourne une exception au lieu de la contrainte CHECK retour False..)

Alternative: Pour ces raisons, j'ai finalement décidé de résoudre ce problème par un déclencher. Mais j'apprécie certainement les idées sur la révision de cette contrainte CHECK afin qu'elle réalise vraiment l'objectif.