I am trying to build a trigger function to automatically update parent order values any time any of it's items changes.
This is what I have created:
CREATE OR REPLACE FUNCTION update_totals() RETURNS void AS $$
UPDATE orders SET
total_fees = (SELECT SUM(fees) FROM order_items WHERE order_id = OLD.order_id),
total_profit = (CASE WHEN total_cost IS NOT NULL THEN total - total_tax - total_cost - (SELECT SUM(fees) FROM order_items WHERE order_id = OLD.order_id) ELSE NULL END)
WHERE id = OLD.order_id;
$$
LANGUAGE SQL;
CREATE TRIGGER update_totals AFTER INSERT
OR UPDATE OF fees
ON order_items INITIALLY DEFERRED
FOR EACH ROW
WHEN ( OLD.* IS DISTINCT FROM NEW.* ) EXECUTE PROCEDURE update_totals();
When I try to run this, I get this error:
missing FROM-clause for table "old"
I tried creating a reference to the original table in the trigger:
CREATE TRIGGER update_totals AFTER INSERT
OR UPDATE OF fees
ON order_items
REFERENCING OLD ROW AS old_order
DEFERRABLE INITIALLY DEFERRED
FOR EACH ROW
WHEN ( OLD.* IS DISTINCT FROM NEW.* ) EXECUTE PROCEDURE update_totals();
But that just gives the error syntax error at or near "REFERENCING"
.
How do I get the order_id
from the original order_items
table?
Best Answer
Firstly, to create a trigger on the
order_items
table, theupdate_totals()
must be a trigger function whichRETURNS TRIGGER
(bold is mine).If not, It causes an error
ERROR: function func_order_items must return type trigger
.Secondly, please remember that you cannot have
OLD
whenAFTER INSERT
on the trigger. If not, It raises an errorERROR: record "old" is not assigned yet
.Finally, please take a look at the example as below: