Domanda

I've created the following table:

CREATE TABLE updates
(
  "table" text,
  last_update timestamp without time zone
)

I want to update it whenever any table is updated, the problem is I don't know how, could someone please help me turn this pseudocode into a trigger?

this = current table on whitch operation is performed
ON ALTER,INSERT,DELETE {
  IF (SELECT COUNT(*) FROM updates where table = this) = 1
  THEN 
    UPDATE updates SET  last_update = timeofday()::timestamp WHERE `table`=this
  ELSE
    INSERT INTO updates VALUES (this,timeofday()::timestamp);
}
È stato utile?

Soluzione

You need a trigger function that is called whenever one of your tables is "updated", assuming that you mean that an INSERT, UPDATE, or DELETE is successfully executed. That trigger function would look like this:

CREATE FUNCTION log_update() RETURNS trigger AS $$
BEGIN
  UPDATE updates SET last_update = now() WHERE "table" = TG_TABLE_NAME;
  IF NOT FOUND THEN
    INSERT INTO updates VALUES (TG_TABLE_NAME, now());
  END IF;
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  ELSE
    RETURN NEW;
  END IF;
END; $$ LANGUAGE PLPGSQL;

Every table that has to be logged this way needs to have a trigger associated with it like this:

CREATE TRIGGER ZZZ_mytable_log_updates
AFTER INSERT OR UPDATE OR DELETE ON mytable
FOR EACH ROW EXECUTE PROCEDURE log_update();

A few comments:

  • Trigger functions are created with PL/PgSQL; see chapter 40 in the documentation. Trigger functions come with some automatic parameters such as TG_TABLE_NAME.
  • Don't use reserved words ("table" in your case) as column names. Actually, in this case you are better off using the oid of the table, with the associated TG_RELID automatic parameter. It takes up less storage, it is faster, and it avoids confusion between tables with the same name in different schemas of your database. You can use the pg_tables system catalog table to look up the table name from the oid.
  • You must return the proper value depending on the operation, or the operation may fail. INSERT and UPDATE operations need to have NEW returned; DELETE needs to have OLD returned.
  • The name of the trigger starts with "ZZZ" to make sure that it fires after any other triggers on the same table have succeeded (they are fired in alphabetical order). If a prior trigger fails, this trigger function will not be called, which is the proper behaviour because the insert, update or delete will not take place either.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top