2017-10-10 65 views
1

我想爲我的一個db表的出生日期字段設置一個約束。基本上我想確保pat_dob_dt至少在16年前(從當前日期起)。我使用PostgreSQL 20年4月8日和指導使用herePostgreSQL觸發器/確保日期過去的函數

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(); 

不幸的是,我遇到了以下錯誤

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 

不知道我要去的地方錯了,因爲我下面的PSQL文檔8.4

編輯 分號固定功能問題。我也得到一個錯誤對我觸發

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

回答

3

嘗試:

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

CREATE OR REPLACE TRIGGER 

,因爲它不工作或更換會失敗 - 只使用CREATE TRIGGER代替

也爲什麼不CHECK缺點traints?例如:

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 

更新

在現有的不符合檢查約束先前的值的情況下 - 你可以推遲檢查與NOT VALID,如:

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

錯誤盯着我。現在我的觸發器出現錯誤。我沒有考慮CHECK約束。我假設這會更快? – moadeep

+0

是的 - 我認爲它會更快更整潔 –

+0

不幸的是,我們的一些舊記錄已經違反了約束條件。需要一些時間來清理數據庫。用觸發器可能會更快。任何想法爲什麼我的觸發錯誤? – moadeep

1

您在錯過了分號隊伍的盡頭。

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