PostgreSQL触发器/函数以确保日期为过去

PostgreSQL触发器/函数以确保日期为过去,sql,postgresql,plpgsql,database-trigger,Sql,Postgresql,Plpgsql,Database Trigger,我想对我的一个db表的“出生日期”字段设置一个约束。基本上,我想确保pat_dob_dt至少是16年前(从当前日期算起)。我使用的是PostgreSQL 8.4.20,用于指导: 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 - int

我想对我的一个db表的“出生日期”字段设置一个约束。基本上,我想确保pat_dob_dt至少是16年前(从当前日期算起)。我使用的是PostgreSQL 8.4.20,用于指导:

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
我不确定哪里出了问题,因为我正在遵循8.4版的psql文档

编辑 分号修复了函数问题。我的触发器也会出错

错误:字符19处“触发器”处或附近的语法错误
第1行:在更新之前创建或替换触发患者日期…

尝试:

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 TRIGGER

还有,为什么不检查约束?例如:

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
尝试:

将失败,因为它无法使用或替换-只需使用
CREATE TRIGGER

还有,为什么不检查约束?例如:

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

你漏了行末的分号

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

你漏了行末的分号

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

错误就在眼前。现在我的触发器出错了。我没有考虑支票约束。我想这会更快?不幸的是,我们的一些旧记录已经违反了约束。清理数据库需要一些时间。用扳机可能会更快。知道我的触发器出错的原因吗?我会删除
语句中的
或替换
语句中的
。。。让我看看文档,这样您就可以
添加约束无效
跳过对现有无效值的检查,同时使用constraintExcellent。谢谢你的帮助,我的错误就在眼前。现在我的触发器出错了。我没有考虑支票约束。我想这会更快?不幸的是,我们的一些旧记录已经违反了约束。清理数据库需要一些时间。用扳机可能会更快。知道我的触发器出错的原因吗?我会删除
语句中的
或替换
语句中的
。。。让我看看文档,这样您就可以
添加约束无效
跳过对现有无效值的检查,同时使用constraintExcellent。谢谢你的帮助