I have a table tbl
which has a dirty: boolean
column. During the transaction, for certain rows this flag is set to true
. Then, I have the following trigger:
create function tbl_process() returns trigger as
$$ begin
-- first, do something for all rows with dirty flag set to true
...
-- then, reset the dirty flag
update tbl set dirty = false where dirty = true;
return null;
end $$ language plpgsql;
create trigger tbl_process after update on tbl for each statement execute procedure tbl_process();
The problem here is that the second query ( update tbl set dirty = false where dirty = true
) calls the trigger recursively. This keeps on going until we get a stack overflow.
Is there a way to avoid this? And also, why are we running into recursion? In the first iteration, we mark all rows as dirty = false
, so in the second iteration, there should be no rows for which dirty = true
?
I am using PostgreSQL 9.6.
Add this below statement at the start of function body
IF pg_trigger_depth() <> 1 THEN
RETURN NEW;
END IF;
like
create function tbl_process() returns trigger as
$$ begin
IF pg_trigger_depth() <> 1 THEN
RETURN NEW;
END IF;
update tbl set dirty = false where dirty = true;
return null;
end $$ language plpgsql;
You could validate if the NEW value for this field is true before updating. If it is set to false you shouldn't have to do anything.
But, why do you process all records where this field is set? Because of this trigger there only should be this one, because in the end it is resetted. And if you need to update the current record you can do that properly by updating the NEW.dirty to false.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.