简体   繁体   中英

How can I avoid infinite recursion in this FOR EACH STATEMENT trigger?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM