Update a table with a trigger after update

后端 未结 3 2037
礼貌的吻别
礼貌的吻别 2020-12-21 09:36

I have two tables

 batch (batch_id,start_date,end_date,batch_strength,is_locked)
 sem (user_id,is_active,no_of_days)

I have executed the tr

3条回答
  •  猫巷女王i
    2020-12-21 09:53

    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:

    • Since the trigger function does the same for every row, I changed it into a potentially much cheaper statement-level trigger.

    • Consequently, I made the trigger function RETURN NULL, because, I quote the manual here:

    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;
      

提交回复
热议问题