Second trigger result disappear [closed]

笑着哭i 提交于 2021-02-11 12:51:40

问题


Please advise were result of trigger tr_stock_plus disappear? Because after INSERT query:

INSERT INTO test.purchase(
import_id, product_id, usd_price, qty)
VALUES (2, 'CG-003', 40, 40);

I have normal reply, no error message:

INSERT 0 1
Query
returned successfully in 242 msec.

Data inserted in

test.purchase

import_id product_id usd_price euro_price qty
2 CG-003 33 33 40

and first trigger for currency convertion also works well, but no changes in second targeted table

test.stock

product_id stock_qty stock_price stock_amount
CG-003 null null null

    CREATE TABLE test.purchase
(
    import_id integer NOT NULL,
    product_id text COLLATE pg_catalog."default",
    usd_price numeric(10,2),
    euro_price numeric(10,2),
    qty integer
)

CREATE TRIGGER tr_p
    AFTER INSERT OR UPDATE OF usd_price
    ON test.purchase
    FOR EACH ROW
    EXECUTE PROCEDURE test.f_conv();

CREATE FUNCTION test.f_conv()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
UPDATE test.purchase pr
SET euro_price = usd_price / i.rate
FROM  test.imports i
WHERE pr.import_id = i.import_id;
RETURN NEW;
END

CREATE TRIGGER tr_stock_plus
AFTER INSERT
ON test.purchase
FOR EACH ROW
EXECUTE PROCEDURE test.f_stock_plus();

CREATE FUNCTION test.f_stock_plus()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
UPDATE test.stock s
SET stock_qty = stock_qty + 
(SELECT pr.qty
FROM test.purchase pr   
WHERE pr.product_id = s.product_id);
RETURN NEW;
END

CREATE TABLE test.stock
(
    product_id text COLLATE pg_catalog."default" NOT NULL,
    stock_qty numeric(10,0),
    stock_price numeric(10,2),
    stock_amt numeric(10,2),
    CONSTRAINT stock_pkey PRIMARY KEY (product_id)
)

回答1:


Ideas to make the process simpler to follow. See comments at end.

CREATE TRIGGER tr_p
    BEFORE INSERT OR UPDATE OF usd_price
    ON test.purchase
    FOR EACH ROW
    EXECUTE PROCEDURE test.f_conv();

CREATE FUNCTION test.f_conv()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
    conv_rate = numeric;
BEGIN
   SELECT INTO 
      conv_rate 
   FROM  
      test.imports i
   WHERE NEW.import_id = i.import_id;

   NEW.euro_price = usd_price / conv_rate;
   RETURN NEW;
END

CREATE TRIGGER tr_stock_plus
BEFORE INSERT
ON test.purchase
FOR EACH ROW
EXECUTE PROCEDURE test.f_stock_plus();

CREATE FUNCTION test.f_stock_plus()
RETURNS trigger

LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
   UPDATE 
      test.stock s
   SET 
      stock_qty = stock_qty + NEW.qty
   WHERE 
      NEW.product_id = s.product_id;
   RETURN NEW;
END

Convert to BEFORE triggers to allow for directly passing in new values to table. Also avoids sub-selects. I would also advise either setting columns to NOT NULL or if not providing a DEFAULT value e.g. 0 for numeric/integer fields.



来源:https://stackoverflow.com/questions/65286820/second-trigger-result-disappear

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!