【发布时间】:2017-06-08 06:07:10
【问题描述】:
假设我们有:
create table T
(
id bigserial primary key
, a int
, b int
, c int
);
我希望c 始终等于a+b,并且我想防止手动更改c。所以我创建了两个触发器:
-- Prevents manual changes of c:
create or replace function no_changes() returns trigger as $$
begin
if old.c is distinct from new.c then
raise exception 'Can''t change c manually.';
end if;
return new;
end;
$$ language plpgsql;
create trigger no_changes
before update of c -- 'before' so prevents changes in 'c'
on T
for each row
execute procedure no_changes();
-- Do c = a + b:
create or replace function change() returns trigger as $$
begin
update T
set c = a + b
where id = new.id;
return new;
end;
$$ language plpgsql;
create trigger change
after insert or update of a, b -- 'after' so I'm sure the row is inserted/updated
on T
for each row
execute procedure change();
如果我这样做:
update T set c = 247;
我看到错误消息“无法手动更改 c”并且该列没有更改。太好了。
但是,如果我这样做:
insert into T (a, b) values (4, 3);
或者:
update T set a = 3 where id = 2 -- suppose id = 2 exists
然后我收到与以前相同的错误消息。显然,来自change 触发器的update 命令会触发no_changes 触发器,从而阻止c 列中的更新。
有什么想法吗?谢谢!
【问题讨论】:
标签: postgresql triggers plpgsql database-trigger