【问题标题】:Postgresql using Trigger to update column values after inserting valuesPostgresql 使用触发器在插入值后更新列值
【发布时间】:2021-10-26 10:06:57
【问题描述】:

我想将值插入到 tableA 中,然后更新列 [amount_hkd]。 我已经成功使用了触发器,但是性能真的很慢,应用触发器后需要一个小时才能完成 8400 行的插入。 我怎样才能提高性能? 感谢您的帮助

要执行的语句:

INSERT INTO tableA (suppliers, invoice_dates, shipment_dates, amounts, currency, currency_conversion_rate)
SELECT l.supplier, l.invoice_date, l.shipment_date, l.amount, l.currency, o.currency_conversion_rate
FROM tableB l
LEFT JOIN tableC o
ON l.currency = o.currency_code
WHERE l.supplier = 'ABC'

我创建的函数:

CREATE OR REPLACE FUNCTION cal() 
RETURNS TRIGGER AS $$ 
BEGIN 
UPDATE tableA 
SET amount_hkd = NEW.amounts * NEW.currency_conversion_rate;
RETURN NEW; 
END; 
$$ LANGUAGE plpgsql;

我尝试的第一个触发器:

CREATE CONSTRAINT TRIGGER update_amount
AFTER INSERT ON tableA
DEFERRABLE
INITIALLY DEFERRED
FOR EACH ROW 
EXECUTE PROCEDURE cal();

我尝试的第二个触发器:

CREATE TRIGGER update_amount 
AFTER INSERT ON tableA
FOR EACH ROW 
EXECUTE PROCEDURE cal();

【问题讨论】:

  • 你需要一个BEFORE触发器FOR EACH ROW
  • 每次插入时,您的触发器都会更新 all 行,而 amount_hkd 的值相同。这就是为什么它很慢。这是你真正需要的吗?

标签: sql postgresql triggers sql-update sql-insert


【解决方案1】:

在插入后更新行是非常低效的。更好的是使用BEFORE 触发器,它可以修改插入的新行之前

CREATE OR REPLACE FUNCTION cal() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN 
   NEW.amount_hkd := NEW.amounts * NEW.currency_conversion_rate;
   RETURN NEW; 
END;$$;

CREATE TRIGGER update_amount 
   BEGORE INSERT ON tableA FOR EACH ROW 
   EXECUTE PROCEDURE cal();

【讨论】:

    【解决方案2】:

    您没有指定您的 Postgres 版本,但如果至少 V12,您可以完全避免触发器。将列amount_hkd 定义为生成列。您不仅避免了触发器,而且还消除了更新currency_conversion_rate 和/或amount 以及忘记更新amount_hkd 或直接更新到amount_hkd 的维护问题。比如:(见example here

    create table table_a( a_id integer generated always as identity 
                        , amounts  decimal
                        , currency_conversion_rate decimal
                        , amount_hkd decimal generated always as ( amounts * currency_conversion_rate ) stored
                        ); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      相关资源
      最近更新 更多