如何正确编写代替更新触发器?
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
将花费更长的时间,因为调用触发器是一些开销。
顺便说一句,你根本不需要那个触发器。即使没有触发器,像这样的简单视图也可以自动更新。
想象下面的示例,其中 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
将花费更长的时间,因为调用触发器是一些开销。
顺便说一句,你根本不需要那个触发器。即使没有触发器,像这样的简单视图也可以自动更新。