你有几个问题。首先,不要使用单引号来引用函数体,这只会弄得一团糟,请改用美元引号:
create or replace function f() returns trigger as $$
...
$$ language plpgsql;
接下来,这没有任何用处:
select s_date from workers;
这将尝试从中获取所有s_date
值workers
,然后将它们全部丢弃。您想查看触发器的当前行,该行位于NEW
:
NEW
数据类型RECORD
;为行级触发器中的INSERT
/操作保存新数据库行的变量。UPDATE
这个变量NULL
在语句级触发器和DELETE
操作中。
所以你可以看看new.s_date
你感兴趣的日期:
select now()::date into tt;
if tt - new.s_date < 365 then
raise exception 'A message';
end if;
这可能是一个行级before insert or update
触发器,所以您不需要return null;
在这里;来自精美手册:
在操作之前触发的行级触发器有以下选择:
- 它可以返回
NULL
以跳过当前行的操作。这指示执行程序不执行调用触发器的行级操作(插入、修改或删除特定表行)。
- 仅对于行级
INSERT
和UPDATE
触发器,返回的行将成为将被插入或替换正在更新的行的行。这允许触发器函数修改正在插入或更新的行。
因此,您的return null;
意思是“如果新记录有效,则跳过此 INSERT 或 UPDATE”,这不是您想要的。你想return new;
。
您还有一个未使用的变量。你可以使用current_date
而不是你的tt
.
您的函数应该看起来更像这样:
create or replace function control_func() returns trigger as $$
begin
if current_date - new.s_date < 365 then
raise exception 'A message';
end if;
return new;
end;
$$ language plpgsql;