你有几个问题。首先,不要使用单引号来引用函数体,这只会弄得一团糟,请改用美元引号:
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;