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 . . . 当然这一点还没有改变。我在等你。