Update a table with a trigger after update

╄→尐↘猪︶ㄣ 提交于 2019-11-29 16:01:10

There are several ways to prevent the infinite recursion you built into your trigger, the most elegant and performant probably adding a WHERE clause to the UPDATE statement in your trigger function:

CREATE OR REPLACE FUNCTION em_batch_update()
  RETURNS trigger AS
$func$
BEGIN

UPDATE batch b
SET    is_locked = TRUE
FROM   sem s
WHERE  s.is_active
AND    s.user_id = 'OSEM'
AND    b.start_date <= (current_date - s.no_of_days)
AND    b.is_locked IS DISTINCT FROM TRUE; -- prevent infinite recursion!

RETURN NULL;

END
$func$  LANGUAGE plpgsql;

CREATE TRIGGER em_sem_batch
BEFORE UPDATE ON batch
FOR EACH STATEMENT
EXECUTE PROCEDURE em_batch_update();

I changed a few other things to move towards sanity:

Trigger functions invoked by per-statement triggers should always return NULL.

  • batch.is_locked and sem.is_active look like boolean columns. Use a proper boolean data type for them. My code is building on it.

  • I also rewrote your UPDATE query completely. In particular the condition on batch.start_date so that an index can be used if available.

  • If batch.is_locked is defined NOT NULL, the WHERE condition can be simplified to:

        AND    b.is_locked = FALSE;
    

Your UPDATE trigger runs another UPDATE on the same table, which will fire the trigger again, so you get infinite recursion. You probably need to redesign this a little bit, but it's hard to say how without an explanation of what you're trying to do.

Infinite recursion in this case because update trigger will do update operation on table batch and the same will triggered after execution of update statement inside em_sem_batch trigger itself.To prevent this add one column in table and in update statement of trigger update that column also to some value and add an if condition to check whether that column has that constant value if so avoid execution of update statement else execute update statement. See example below:

CREATE FUNCTION public.trigger_fuction()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    NOT LEAKPROOF
AS $BODY$
BEGIN
  IF NEW.data_replicated=true THEN
    UPDATE sample SET data_replicated=false WHERE id=NEW.id;
    raise notice 'changed data replicated of sample with id as %',NEW.ID;
  END IF;
  RETURN NEW;
END;
$BODY$;


CREATE TRIGGER data_replication_trigger
  AFTER UPDATE
  ON sample
  FOR EACH ROW
  EXECUTE PROCEDURE trigger_fuction();

In this example sample table has data_replicated boolean field which will be updated when trigger is executed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!