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