web-dev-qa-db-fra.com

Créez un déclencheur sur toutes les colonnes Last_Modified dans PostgreSQL

Dans PostgreSQL 9.5, j'ai des tables avec des colonnes dans le formulaire

prefix_last_modified timestamp without time zone NOT NULL DEFAULT  (clock_timestamp() AT TIME ZONE 'UTC')

Je cherchais un moyen de définir la dernière valeur modifiée automatiquement mise à jour à chaque mise à jour des lignes, et j'ai trouvé ce joli post qui définissait la fonction:

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

Maintenant, j'aimerais savoir s'il y a un moyen de transmettre le nom de la colonne à la fonction PostgreSQL et de l'exécuter à la ligne NEW ligne? Par exemple.

CREATE OR REPLACE FUNCTION update_modified_column(varchar column)   
    RETURNS TRIGGER AS $$
    BEGIN
        NEW.column = now();
        RETURN NEW; 
    END;
$$ language 'plpgsql';
4
mat_boy

spi module: moddatetime

moddateTime - Fonctions pour suivre la dernière fois de modification

moddatetime() est une gâchette qui stocke l'heure actuelle dans un champ timestamp. Cela peut être utile pour suivre le dernier temps de modification d'une rangée particulière dans une table.

Utiliser, créer un BEFORE UPDATE déclenche à l'aide de cette fonction. Spécifiez un argument de déclenchement unique: le nom de la colonne à modifier. La colonne doit être de type horodatage ou horodatage avec le fuseau horaire.

Il y a un exemple dans moddateTime.example .

Exemple/Synopsis

Du fichier ci-dessus 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

C'est donc ce que vous auriez besoin.

CREATE EXTENSION moddatetime;

CREATE TRIGGER mdt_table
  BEFORE UPDATE ON table
  FOR EACH ROW
  EXECUTE PROCEDURE moddatetime (prefix_last_modified);
6
Evan Carroll

Techniquement, c'est possible. Par exemple:

--drop table if exists t1;
--drop table if exists t2;
--drop function if exists foo();
create table t1(x int, q int);
create table t2(y int, q int);

create function foo() returns trigger language plpgsql as $foo$
begin
  raise info '%', tg_argv[0];
  raise info '%', new; 
  execute $$select (b).* from (select $1 #= hstore($2||'=>666')) as a(b)$$ using new, tg_argv[0] into new;
  raise info '%', new;
  return new;
end $foo$;

create trigger tg_def before insert on t1 for each row execute procedure foo('x');
create trigger tg_def before insert on t2 for each row execute procedure foo('y');

nd@postgres=# insert into t1 values(1,2);
INFO:  x
INFO:  (1,2)
INFO:  (666,2)
INSERT 0 1
nd@postgres=# insert into t2 values(1,3);
INFO:  y
INFO:  (1,3)
INFO:  (666,3)
INSERT 0 1
nd@postgres=# select * from t2;
╔═════╤═══╗
║  y  │ q ║
╠═════╪═══╣
║ 666 │ 3 ║
╚═════╧═══╝

Vous devez installer hstore extension pour ce code.

Cependant, il pourrait extrêmement ralentir les DMLS à cause de execute utiliser.

1
Abelisto