问题
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