PgSQL - trigger to track value changes

155 Views Asked by At

I am trying to write a trigger function in PgSQL for tracking value changes in TableA (trigger after update on TableA). The track record will be stored in TableB.

CREATE TABLE TableA (
  ID SERIAL NOT NULL,
  ANumber integer NOT NULL,
  ADate date  NOT NULL,
  ABoolean boolean NOT NULL
);

-- table for tracking changes
CREATE TABLE TableB (
  ID SERIAL NOT NULL,
  Description varchar(100) NOT NULL
);

The body of trigger procedure should be like following...

    IF NEW.ANumber <> OLD.ANumber then
     INSERT INTO TableB (Description)
      VALUES (CONCAT('The value ', OLD.ANumber, ' changed to ', NEW.ANumber));
     RETURN NEW;
    END IF;
    
   IF NEW.ABoolean <> OLD.ABoolean then
    INSERT INTO TableB (Description)
     VALUES (CONCAT('The value changed to ', NEW.ABoolean ));
    RETURN NEW;
   END IF;

I have found in PgSQL documentation that I need to create trigger like this

CREATE TRIGGER log_changes
AFTER UPDATE ON TableA
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE FUNCTION log_changes();

The problem is if I change multiple columns in TableA. There is only one new record in TableB corresponding to the first column where the value change happend.

Is there any way to solve this?

1

There are 1 best solutions below

0
kofemann On

Take the return statement out of IF block, like this:

IF NEW.ANumber <> OLD.ANumber then
 INSERT INTO TableB (Description)
  VALUES (CONCAT('The value ', OLD.ANumber, ' changed to ', NEW.ANumber));    
END IF;

IF NEW.ABoolean <> OLD.ABoolean then
  INSERT INTO TableB (Description)
    VALUES (CONCAT('The value changed to ', NEW.ABoolean ));
END IF;
RETURN NEW;