Description:
- I am running
postgresql 13 - I have two tables under different schemas,
t1andt2. t2is derivative oft1in the sense that they share all the same columns and data, butt2is always downstream oft1as far as validity.- The rows in both tables share the same primary key, which is what I assume would be used as the link between them.
The ask:
- I would like to create a trigger that reflects any changes in
t1and syncst2to be the same. - I started with
INSERTorUPDATE, but ifDELETEis easily added, I would like to implement that as well.
Trigger Code:
-- Trigger for t1 to t2 --
CREATE OR REPLACE FUNCTION t1_schema.sync_trigger()
RETURNS TRIGGER AS
$$
BEGIN
INSERT INTO t2_schema.t2 (col1, col2, col3)
VALUES (NEW.col1, NEW.col2, NEW.col3);
RETURN NEW;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER t1t2_test_sync
AFTER INSERT OR UPDATE ON t1_schema.t1
FOR EACH ROW
EXECUTE PROCEDURE t1_schema.sync_trigger()
When I execute this code and do a test UPDATE on t1, the same row on t2 does not reflect the changes or give me any errors.
I have tried:
- Discretely labeling all rows as updated with
NEW.format, but run into the problem of primary key column not being editable int2. - Adding a
WHEREclause after theVALUESclause, something likeWHERE primary_key=NEW.primary_key, but I get an error. - Another option I have seen is adding an
IFstatement before theINSERT, or adding aWHENclause in the trigger, but neither have worked.
(A) Solution based on triggers
You maybe get an error when updating a row in
t1because your trigger function tries to insert a new row int2which has alreday been inserted int2by the same trigger function when it has been inserted int1. You need to duplicate and specialize your trigger functions, one for insert, one for update, one for delete because the treatment to be triggered ont2is different :(B) Solution based on foreign key
It is possible that a foreign key on
t2 (col1,col2,col3)referencingt1 (col1, col2, col3)with the optionsON UPDATE CASCADE ON DELETE CASCADEmay deliver your expected result in a much more simple and efficient way, see the manual. In this case, you don't need the triggersON UPDATEandON DELETEanymore, but you still need the triggerON INSERT.