Cosa c'è di sbagliato nel mio vincolo di controllo Oracle 10gr2? Prova di imporre un intervallo di date
-
03-07-2019 - |
Domanda
Voglio applicare il vincolo CHECK su un intervallo di date in modo tale che tutte le date nella colonna BIRTH_DATE siano inferiori a domani e maggiori o uguali a 100 anni fa. Ho provato questa espressione in un vincolo CHECK:
BIRTH_DATE >= (sysdate - numtoyminterval(100, 'YEAR')) AND BIRTH_DATE < sysdate + 1
Ma ho ricevuto l'errore " ORA-02436: data o variabile di sistema erroneamente specificata nel vincolo CHECK "
Esiste un modo per ottenere ciò utilizzando un vincolo CHECK anziché un trigger?
Soluzione
L'espressione di un vincolo di controllo deve essere deterministica, quindi questo tipo di intervallo di date scorrevole non è applicabile in un vincolo di controllo. Dal Riferimento SQL
Le condizioni dei vincoli di controllo non possono contiene i seguenti costrutti:
* Subqueries and scalar subquery expressions * Calls to the functions that are not deterministic (CURRENT_DATE,
CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER e USERENV)
Altri suggerimenti
Per quanto riguarda il motivo per cui Oracle fa questa restrizione: i vincoli di controllo devono sempre essere valutati su VERO, anche per gli aggiornamenti. Se hai aggiunto un 99enne al database e poi hai provato ad aggiornare l'indirizzo e-mail della persona (ad es.) Tra 2 anni riceveresti una violazione del vincolo di controllo.
Quello che potresti fare, se appropriato, è avere un'altra colonna CREATED_DATE che per impostazione predefinita è SYSDATE e rendere il vincolo:
BIRTH_DATE >= (CREATED_DATE - numtoyminterval(100, 'YEAR'))
AND BIRTH_DATE < CREATED_DATE + 1
Tuttavia, se davvero si desidera eseguire il controllo al momento INSERT, farlo in un trigger di database o nel codice API.