2016-09-27 2 views
0

Ich würde gerne wissen, was ich falsch mache,eine Einschränkung für SYSDATE minus ein Geburtsdatum

Ich möchte eine CHECK-Einschränkung in Oracle hinzufügen, um sicherzustellen, dass ein Benutzer über 18

Also habe ich

ALTER TABLE User 
ADD CONSTRAINT check_age CHECK(TO_CHAR(SYSDATE, 'yyyy/mm/dd')- TO_CHAR(dateOfBirth, 'yyyy/mm/dd')> 18) 

Aber Im Empfangsfehler

Ursache: Es wurde versucht, ein Datum konstant oder System v verwenden Ariable, wie USER, in einer Prüfbedingung, die in einer CREATE TABLE- oder ALTER TABLE-Anweisung nicht vollständig angegeben wurde. Für Beispiel wurde ein Datum ohne das Jahrhundert angegeben. * Aktion: Geben Sie die Datumskonstante oder die Systemvariable vollständig an. Einstellen der Veranstaltung 10149 erlaubt Einschränkungen wie „a1> '10 âMAY-96' “, , die einen Fehler vor dem 8. Version erstellt werden dürfen

Warum es falsch ist?

Ich verstehe immer noch nicht, warum ich es nicht hinzufügen können, und ich würde freundlich lieben, wenn es mir jemand

Dank

+3

Oracle erlaubt Ihnen nicht, 'sysdate' für eine Einschränkung zu verwenden, da dies nur überprüft werden kann, wenn der Datensatz erstellt wird. –

+1

Als Alternative können Sie einen Trigger verwenden – cha

+1

Als allgemeine Philosophie macht es nicht wirklich Sinn, "Constraints" zu haben, die erfüllt sein können oder nicht, je nachdem, ob sie "jetzt" oder "in zehn Minuten" bewertet werden. (wörtlich, da SYSDATE eine Uhrzeit-Komponente hat). Dieselbe Bedingung, heute oder morgen evaluiert, sollte zum gleichen Ergebnis führen. – mathguy

Antwort

1

Ab Oracle 11g erklären können, wenn Sie nicht direkt verwenden können sysdate in einer Einschränkung, können Sie den gleichen Effekt mit einer virtuellen Spalte erhalten:

create function over_18 ( 
    p_birth_date in User.dateOfBirth%type 
) return varchar2 deterministic is 

begin 
    return case when months_between(sysdate, p_birth_date) /12 > 18 then 'Y' else 'N' end; 
end over_18; 
/

alter table User add (over_18_ind as (cast(over_18(dateOfBirth) as varchar2(1)))); 
/

alter table User add constraint check_age check (over_18_ind = 'Y'); 
/

Basierend auf einem Artikel here. Auch wenn Oracle die Verwendung von sysdate in einer Integritätsbedingung zulässt, würde Ihre Integritätsbedingung trotzdem nicht funktionieren, da die Formate, in die Sie Ihre Datumsangaben konvertiert haben, nicht implizit in Zahlen subtrahiert werden können (ich habe eine alternative Altersüberprüfung bereitgestellt).

+0

Danke, das war mir nicht bewusst, weil Oracle uns erlaubt, SYSDATE in jeder normalen Abfrage zu verwenden, die ich gerade nicht wusste. Es war in einer Einschränkung verboten – napi15