如何正确编写代替更新触发器?

How to write an instead of update trigger correctly?

想象下面的示例,其中 table t 和视图 v.

create table t (a int, b int, c int);
insert into t values (1, 2, 3);
create view v as select * from t;

现在我想以这种方式为视图编写一个“而不是更新”触发器,视图的所有更新都会更新 table。我知道在这个简化的例子中我不需要它,因为 PostgreSQL 可以自动完成。但在我的真实世界用例中,这是必要的。

这是实现更新触发器的正确​​方法吗?

create function u () returns trigger as $$
begin
  update t set a = new.a, b = new.b, c = new.c;
  return new;
end;
$$ language plpgsql;
create trigger t instead of update on v
for each row execute procedure u ();

我不确定,因为我想知道 table 和视图的更新是否有区别:

update t set a = 0 where a = 1;
update v set a = -1 where a = 0;

我希望 table 的更新只更新一列。但我担心视图的更新会更新 table.

中的三列

是这样吗?如果是这样,如何解决这个问题?

对 table 的任何更新,无论它修改了多少行,都将始终写入相同数量的数据。原因是 UPDATE 创建了完整行的新版本。

视图上的 UPDATE 将花费更长的时间,因为调用触发器是一些开销。

顺便说一句,你根本不需要那个触发器。即使没有触发器,像这样的简单视图也可以自动更新。