I have a table that can contain many records for one account: different amounts.
ACCOUNTID | AMOUNT
id1 | 1
id1 | 2
id2 | 3
id2 | 4
Each time a record in this table is inserted / updated / deleted, we need to estimate the total amount to know whether we need to fire the event or not (by inserting data into another table). The amount is calculated based on the sum of the records (at the expense) present in this table.
The calculation of the sum should use the new values of the records, but to check some conditions we will need the old values (for example, the old value was X - the new value is Y: if [X <= threshold and Y> threshold] then trigger the event by inserting the record into another table )
So, in order to compute and trigger the event, we created a trigger in this table. Something like that:
CREATE OR REPLACE TRIGGER <trigger_name>
AFTER INSERT OR UPDATE OR DELETE OF MOUNT ON <table_name>
FOR EACH ROW
DECLARE
BEGIN
1. SELECT SUM(AMOUNT) INTO varSumAmounts FROM <table_name> WHERE accountid = :NEW.accountid;
2. varAmount := stored_procedure(varSumAmounts);
END <trigger_name>;
The problem is that operator 1. throws the following error: "ORA-04091: the table is mutating, the trigger / function may not see it."
We tried the following, but without success (same exception / error), to select all records whose rowId is different from the current rowId:
(SELECT SUM(AMOUNT)
INTO varSumAmounts
FROM <table_name>
WHERE accountId = :NEW.accountid
AND rowid <> :NEW.rowid;)
to calculate the sum as the sum of the sums of all the rows next to the current row + the sum of the current row (which we have in the context of the trigger).
We looked for other solutions, and we found some, but I don’t know which one is better, and what is the disadvantage for each of them (although they are somehow similar)
"table is mutating" 1 2, .
, : OLD : NEW . :
CREATE OR REPLACE TRIGGER trigger-name
FOR trigger-action ON table-name
COMPOUND TRIGGER
BEFORE STATEMENT IS
BEGIN
END BEFORE STATEMENT;
AFTER EACH ROW IS
BEGIN
END AFTER EACH ROW;
AFTER STATEMENT IS
BEGIN
END AFTER STATEMENT;
END trigger-name;
/
"ON COMMIT DELETE ROWS", , , .
, : "ORA-14450: ".
, , oracle , :
" (GTT) Distributed XA .
...
, , XA- .
- XA-, .
...
, , XA , , 5344322.
"
, XA DML , ( ). - ( ), . ?
, : "ORA-04091: , / ", : "ORA-14450: temp ??