i have the following 2 table: runs:
+--------+-------------+
| run_id | status |
+========+=============+
| 1 | active |
+--------+-------------+
| 2 | new |
+--------+-------------+
and orders:
+----------+--------+--------------+
| order_id | run_id | order_status |
+==========+========+==============+
| 1 | 1 | finished |
+----------+--------+--------------+
| 2 | 1 | finished |
+----------+--------+--------------+
| 3 | 1 | active |
+----------+--------+--------------+
| 4 | 2 | new |
+----------+--------+--------------+
| 5 | 2 | active |
+----------+--------+--------------+
| 6 | 2 | active |
+----------+--------+--------------+
it is requested to implement the following logic: when all orders in the run have the same status the run status should be updated (to be the same as its orders).
for example when the the order_id = 3
status is set to 'finished'
then the run_id=1
status should be set to 'finished'
too. the same with order_id = 4
when it takes the status 'active'
then run_id = 2 should
set to 'active'
too.
the procedure responsible of checking orders status and updating run status accordingly:
CREATE OR REPLACE PROCEDURE check_and_update_run_status (in_order_id IN orders.order_id%TYPE,
in_run_id IN runs.run_id%TYPE,
in_order_status IN orders.order_status%TYPE)
AS
v_update_run VARCHAR2(1) := 'N';
BEGIN
/*query the table ORDERS and check if all orders in the given in_run_id having the same status as in_order_status: */
SELECT CASE
WHEN NOT EXISTS ( SELECT *
FROM ( SELECT order_id,
order_status
FROM orders
WHERE run_id = in_run_id )
WHERE order_status <> in_order_status )
THEN 'Y'
END
INTO v_update_run
FROM dual;
IF v_update_run THEN
UPDATE runs
SET run_status = in_order_status
WHERE run_id = in_run_id;
END IF;
END check_and_update_run_status;
and I've created the trigger
CREATE OR REPLACE TRIGGER trigger1
AFTER INSERT OR UPDATE OF order_status ON orders FOR EACH ROW
BEGIN
check_and_update_run_status( in_order_id => :new.order_id,
in_run_id => :new.run_id,
in_po_status => :new.order_status );
END;
the logic is failing because the error: ORA-04091: table ORDERS is mutating, trigger/function may not see it
.
the trigger is calling a procedure which querying the same table the trigger is invoked against.
what would the best way to solve such a problem?