So I am working on adding a last updated time to the database for my app's server. The idea is that it will record the time an update is applied to one of our trips and then the app can send a get request to figure out if it's got all of the correct up to date information.
I've added the column to our table, and provided the service for it all, and finally manage to get a trigger going to update the column every time a change is made to a trip in it's trip table. My problem now comes from the fact that the information that pertains to a trip is stored across a multitude of other tables as well (for instance, there are tables for the routes that make up a trip and the photos that a user can see on the trip, etc...) and if any of that data changes, then the trip's update time also needs to change. I can't for the life of me figure out how to set up the trigger so that when I change some route information, the last updated time for the trip(s) the route belongs to will be updated in it's table.
This is my trigger code as it stands now: it updates the trip table's last updated column when that trip's row is updated.
CREATE OR REPLACE FUNCTION record_update_time() RETURNS TRIGGER AS
$$
BEGIN
NEW.last_updated=now();
RETURN NEW;
END;
$$
LANGUAGE PLPGSQL;
CREATE TRIGGER update_entry_on_entry_change
BEFORE UPDATE ON mydatabase.trip FOR EACH ROW
EXECUTE PROCEDURE record_update_time();
--I used the next two queries just to test that the trigger works. It
--probably doesn't make a difference to you but I'll keep it here for reference
UPDATE mydatabase.trip
SET title='Sample New Title'
WHERE id = 2;
SELECT *
FROM mydatabase.trip
WHERE mydatabase.trip.id < 5;
Now I need it to update when the rows referencing the trip row with a foreign key get updated. Any ideas from someone more experienced with SQL triggers than I?
"mydatabase" is a remarkably unfortunate name for a schema.
The trigger function could look like this:
CREATE OR REPLACE FUNCTION trg_upaft_upd_trip()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
UPDATE mydatabase.trip t -- "mydatabase" = schema name (?!)
SET last_updated = now()
WHERE t.id = NEW.trip_id -- guessing column names
RETURN NULL; -- calling this AFTER UPDATE
END
$func$;
And needs to be used in a trigger on every related table (not on trip
itself):
CREATE TRIGGER upaft_upd_trip
AFTER UPDATE ON mydatabase.trip_detail
FOR EACH ROW EXECUTE PROCEDURE trg_upaft_upd_trip();
You also need to cover INSERT
and DELETE
(and possibly COPY
) on all sub-tables ...
This approach has many potential points of failure. As alternative, consider a query or view that computes the latest last_updated
from sub-tables dynamically. If you update often this might be the superior approach.
If you rarely UPDATE
and SELECT
often, your first approach might pay.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With