Sql 插入或更新期间列上的Postgres和math

Sql 插入或更新期间列上的Postgres和math,sql,postgresql,Sql,Postgresql,当插入或更新数据时,我希望能够对两列执行一些数学运算,并将其作为第三列的值输入 表架构: CREATE TABLE "public"."subscriptions" ( "id" int4 NOT NULL DEFAULT nextval('subscriptions_id_seq'::regclass), "item" varchar, "amount" float4,

当插入或更新数据时,我希望能够对两列执行一些数学运算,并将其作为第三列的值输入

表架构:

CREATE TABLE "public"."subscriptions" (
    "id" int4 NOT NULL DEFAULT nextval('subscriptions_id_seq'::regclass),
    "item" varchar,
    "amount" float4,
    "yearly_recurrance" int2,
    "annual_cost" float4,
    "rank" int2,
    PRIMARY KEY ("id")
);
插入语句:

INSERT INTO "public"."subscriptions" ("item", "amount", "yearly_recurrance", "rank") VALUES ('test', '19', '7', '0');
我已经创建了一个函数和触发器,在我的脑海中,它应该取金额并乘以年度复发率,然后将结果输入年度成本字段

功能:

CREATE OR REPLACE FUNCTION public.calc_cost()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$
BEGIN
NEW.annual_cost = NEW.amount * NEW.yearly_recurrance;
RETURN NEW;
END;

$function$
触发:

CREATE TRIGGER calc_cost BEFORE INSERT or UPDATE ON subscriptions
FOR EACH STATEMENT
EXECUTE PROCEDURE calc_cost();
这不符合我的期望。相反,insert语句中的值被放在它们所属的位置,但函数似乎没有运行。我看不到任何错误


我应该提到,我相信触发器正在工作并调用函数。如果我在函数中放入垃圾,就会出现错误。我认为问题出在功能上。然而,鉴于这是我的第一个函数,我不确定如何处理未提交的数据。也许这是不可能的。

使用生成的列:

alter table subscriptions
    add annual_cost float4 generated always as (amount * yearly_recurrance) stored;
没有触发开销,而且总是准确的


注意:我不建议对货币金额进行浮动;舍入误差可能会有问题。使用
numeric

这应该和您期望的一样有效。也许你可以想出一个完整的可重复的测试用例,如果你使用V12或以上,考虑使用一个生成的列。但这并不能解释为什么你的触发器解决方案不起作用。原因是您有一个语句级触发器。该触发器在处理任何实际数据之前触发一次。此时的新数据值为空。触发器的工作方式是将“for each statement”更改为“for each row”。请看,我喜欢这个建议,但我在更改表时遇到以下错误:
Query 1错误:错误:语法错误位于或接近“;”第2行:…生成的st数值始终为(金额*年重现期)我删除了该列并将其退回。工作得很漂亮。谢谢Postgres只支持
存储的
生成的列,而不支持在select@a_horse_with_no_name . . . 当然这一点还没有改变。我在等你。