2017-10-10 1 views
1

Ich möchte eine Einschränkung auf ein Geburtsdatum Feld für eine meiner db-Tabellen setzen. Im Wesentlichen möchte ich sicherstellen, dass pat_dob_dt vor mindestens 16 Jahren (ab dem aktuellen Datum) ist. Ich bin mit PostgreSQL 8.4.20 und here zur Orientierung verwendet:PostgreSQL Trigger/Funktion zu gewährleisten, dass das Datum in der Vergangenheit ist

CREATE OR REPLACE FUNCTION patient_dob_in_past() 
RETURNS TRIGGER AS $$ 
BEGIN 
-- check pat_dob_dt is in past -- 
    IF (NEW.pat_dob_dt > current_date - interval '16 years') THEN 
     RAISE EXCEPTION '% must be 16 years in past', NEW.pat_dob_dt 
    END IF; 
    RETURN NEW; 
END; 
$$ language 'plpgsql'; 


CREATE OR REPLACE TRIGGER patient_dob_in_past BEFORE UPDATE OR INSERT 
ON patients FOR EACH ROW EXECUTE PROCEDURE patient_dob_in_past(); 

Leider bin ich mit dem folgenden Fehler traf

ERROR: syntax error at or near "END" at character 14 
QUERY: SELECT $1 END IF 
CONTEXT: SQL statement in PL/PgSQL function "patient_dob_in_past" near line 4 
LINE 1: SELECT $1 END IF 

nicht sicher, wo ich falsch werde, da ich die psql docs bin nach für 8.4

BEARBEITEN Semikolon behoben Funktionsproblem. Ich habe auch einen Fehler für meine Trigger

ERROR: syntax error at or near "TRIGGER" at character 19 LINE 1: CREATE OR REPLACE TRIGGER patient_dob_in_past BEFORE UPDATE ...

Antwort

3

Versuch:

CREATE OR REPLACE FUNCTION patient_dob_in_past() 
RETURNS TRIGGER AS $$ 
BEGIN 
-- check pat_dob_dt is in past -- 
    IF (NEW.pat_dob_dt > current_date - interval '16 years') THEN 
     RAISE EXCEPTION '% must be 16 years in past', NEW.pat_dob_dt; 
    END IF; 
    RETURN NEW; 
END; 
$$ language 'plpgsql'; 

https://www.postgresql.org/docs/current/static/sql-createtrigger.html auch

CREATE OR REPLACE TRIGGER 

wird fehlschlagen, da es nicht mit funktioniert OR REPLACE - verwenden nur CREATE TRIGGER statt

auch warum nicht KONTROLL KONSE Trains? zB:

t=# create table q2(t timestamptz check (t < now() - '16 years'::interval)); 
CREATE TABLE 
t=# insert into q2 select now(); 
ERROR: new row for relation "q2" violates check constraint "q2_t_check" 
DETAIL: Failing row contains (2017-10-10 11:41:01.062535+00). 
t=# insert into q2 select now() - '16 years'::interval; 
ERROR: new row for relation "q2" violates check constraint "q2_t_check" 
DETAIL: Failing row contains (2001-10-10 11:41:13.031769+00). 
t=# insert into q2 select now() - '16 years'::interval -'1 second'::interval; 
INSERT 0 1 

Update

Bei früheren Werten bestehenden, die Check-Einschränkung nicht übereinstimmen - Sie können überprüfen, verzögern mit NOT VALID, zB:

t=# create table q2(t timestamptz); 
CREATE TABLE 
t=# insert into q2 select now(); 
INSERT 0 1 
t=# alter table q2 add constraint q2c check (t < (now() - '16 years'::interval)) not valid; 
ALTER TABLE 
t=# insert into q2 select now(); 
ERROR: new row for relation "q2" violates check constraint "q2c" 
DETAIL: Failing row contains (2017-10-10 11:56:02.705578+00). 
+0

Fehler starrte mich ins Gesicht. Jetzt habe ich einen Fehler mit meinem Auslöser. Ich hatte keine CHECK-Einschränkung in Betracht gezogen. Ich nehme an, das wäre schneller? – moadeep

+0

ja - ich nehme an, es wird sowohl schneller als auch ordentlicher sein –

+0

Unglücklicherweise verletzen einige unserer alten Aufzeichnungen bereits eine Beschränkung. Würde einige Zeit brauchen, um die Datenbank zu säubern. Wahrscheinlich schneller mit einem Auslöser. Irgendeine Idee warum meine Auslösefehler? – moadeep

1

Sie verfehlten Semikolon am Ende der Zeile.

RAISE EXCEPTION '% must be 16 years in past', NEW.pat_dob_dt; 
Verwandte Themen