を動作するように別のものを防ぎ、我々が持っていると仮定します。PostgreSQLのトリガーは
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手動で変更できません」と列は変更を行いませんので、私は2つのトリガーを作成します。すばらしいです。私が行う場合
はしかし、:
insert into T (a, b) values (4, 3);
または:
update T set a = 3 where id = 2 -- suppose id = 2 exists
をそれから私は前と同じエラーメッセージが表示されます。明らかに、update
コマンドのchange
トリガーがno_changes
トリガーを起動し、c
列の更新を防止します。
アイデア?ありがとう!
ありがとう、@アベリスト。両方のトリガーを 'before'トリガーにする必要がありますか?代わりに 'after'トリガを使用することはできませんか? –
@RicardoPérezLópezできます。しかし、 'after'トリガで' NEW'変数を使って挿入/更新された行を変更することはできません(コードの主な問題です。 'update'は' before update'トリガを発生させます)。 – Abelisto