使用插入字段中的数据,在Postgres触发程序上进行插入操作,以在另一个字段中插入计算后的数据。

4
假设我有一个名为 X 的表,X 有字段 X1X2X3。我想要一个解决方案,每当我插入 X1X2 的值时,使用触发器自动将 X3 设置为 X1 和 X2 的总和。
这在 mysql 中非常简单,但是经过一段时间的搜索,我找不到 postgres 的好例子,只有一些关于每行触发器的信息,但没有示例。

展示给我们样本数据和期望的结果。请阅读如何提问。这里是一个很好的起点,可以学习如何提高问题质量并获得更好的答案:开始 - Juan Carlos Oropeza
2个回答

7
创建触发器函数:
create or replace function update_calc_column()
  returns trigger
as
$$
begin
  new.x3 := new.x1 + new.x2;
  return new;
end;
$$
language plpgsql;

创建触发器:
create trigger calc_trigger 
   before insert or update on X
   for each row
   execute procedure update_calc_column();

SQLFiddle: http://sqlfiddle.com/#!15/7ed21/1

以上内容基本上是手册中示例的简化版。
http://www.postgresql.org/docs/current/static/plpgsql-trigger.html#PLPGSQL-TRIGGER-EXAMPLE


然而,存储这样的派生数据通常不是一个好主意。您应该只创建一个视图,返回一个定义为 X1 + X2 的列 X3 - 维护代码更少,效率也一样高(实际上更高,因为您可以摆脱触发器的开销)。


另一个(更奇特的)选择是使用 Postgres 的面向对象扩展和创建虚拟列:

create or replace function x3(data X) --<< yes, the type of the parameter is the name of the table 
   returns integer
as
$$
   select data.x1 + data.x2;
$$
language sql;

您可以使用以下方法:

select x.*, x.x3
from x;

SQLFiddle: http://sqlfiddle.com/#!15/53acf/1

然而,这种方法的劣势在于需要 明确地 选择 x3 列。当使用 x.* 时,它不会显示出来。


谢谢,实际上这是为了一个读取频繁的应用程序,其中读取操作的数量级比写入高得多,而且我将拥有数十亿行数据,并且 x 将具有超过 100 个字段。正因为如此,我想存储总和、平均值或某些不同的常用字段,因为这将使报告的生成更快,在 mysql 中肯定是这样,但如果我对 postgres 漏掉了什么,请告诉我。 - sjwbond
如果你需要聚合和其他的计算,最好研究一下物化视图。 - user330315

1
如果您只需要将X3的值计算为X1X2的总和,您可以使用以下方法。
ALTER TABLE yourTable
ADD COLUMN x3 BIGINT GENERATED ALWAYS AS (x1 + x2) STORED;

一个存储生成的列在写入(插入或更新)时进行计算,并占用存储空间,就像一个普通列一样。因此,从性能的角度来看,它也很高效(SELECT 上没有计算)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接