web-dev-qa-db-fra.com

PostgreSQL: mise à jour automatique updated_at avec colonne personnalisée

Avant, je réunissais plusieurs tables en une seule et retournais le résultat, mais dans de nombreuses tables, j'avais les mêmes noms de colonnes. C'est pourquoi j'ai décidé de préfixer les noms de colonne avec le nom de la table. Mais cela a cassé le déclencheur que j'ai dû mettre à jour automatiquement mon updated_at colonne.

C'est la fonction que j'avais:

CREATE OR REPLACE FUNCTION update_updated_at()
  RETURNS TRIGGER AS $$
  BEGIN
      NEW.updated_at = now();
      RETURN NEW;
  END;
  $$ language 'plpgsql';

Et j'ajouterais un déclencheur comme:

CREATE TRIGGER update_users_updated_at
  BEFORE UPDATE ON users
  FOR EACH ROW EXECUTE PROCEDURE update_updated_at();

Mais maintenant, ma colonne s'appelle users_updated_at et cela ne fonctionne pas. Ma question est la suivante: existe-t-il un moyen de transmettre le nom de la colonne au déclencheur et de mettre à jour la colonne transmise, ou existe-t-il une autre méthode que je ne connais pas?

8
Ivanstame

Utilisez le module spi 's moddatetime

module spi, moddatetime

moddatetime - Fonctions de suivi de l'heure de la dernière modification

moddatetime () est un déclencheur qui stocke l'heure actuelle dans un champ timestamp. Cela peut être utile pour suivre la dernière heure de modification d'une ligne particulière dans une table.

Pour l'utiliser, créez un déclencheur BEFORE UPDATE à l'aide de cette fonction. Spécifiez un seul argument déclencheur: le nom de la colonne à modifier. La colonne doit être de type horodatage ou horodatage avec fuseau horaire.

Il y a un exemple dans moddatetime.example .

Exemple/Synopsis

De ce qui précède fichier référencé ,

DROP TABLE mdt;

CREATE TABLE mdt (
    id      int4,
    idesc       text,
    moddate timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL
);

CREATE TRIGGER mdt_moddatetime
    BEFORE UPDATE ON mdt
    FOR EACH ROW
    EXECUTE PROCEDURE moddatetime (moddate);

INSERT INTO mdt VALUES (1, 'first');
INSERT INTO mdt VALUES (2, 'second');
INSERT INTO mdt VALUES (3, 'third');

SELECT * FROM mdt;

UPDATE mdt SET id = 4
    WHERE id = 1;
UPDATE mdt SET id = 5
    WHERE id = 2;
UPDATE mdt SET id = 6
    WHERE id = 3;

SELECT * FROM mdt;

Ton application

Voici donc ce dont vous auriez besoin.

CREATE EXTENSION spi;

ALTER TABLE users ALTER timestamp_at SET DEFAULT now();

DROP TRIGGER IF EXISTS
  update_users_updated_at ON users;

CREATE TRIGGER mdt_users
  BEFORE UPDATE ON users
  FOR EACH ROW
  EXECUTE PROCEDURE moddatetime (timestamp_at);
7
Evan Carroll