Vous pouvez utiliser format()
pour faciliter la création d'une requête SQL dynamique car elle traitera automatiquement correctement les identificateurs et les littéraux. Une chose que les gens oublient généralement est que vous pouvez étendre une seule expression d'enregistrement à toutes ses colonnes en utilisant (...).*
- cela fonctionne aussi pour NEW
et OLD
enregistrer des variables dans un déclencheur, par ex. select (new).*
Vous pouvez également passer des variables à un SQL dynamique avec le using
mot-clé du execute
déclaration. Il n'est pas nécessaire de convertir l'enregistrement dans les deux sens entre un enregistrement et une représentation textuelle.
En utilisant cette possibilité, votre fonction de déclenchement peut être simplifiée pour :
DECLARE
l_sql text;
BEGIN
IF TG_TABLE_SCHEMA = 'public' THEN
newtable := TG_TABLE_NAME || '_actividad';
ELSE
newtable := TG_TABLE_SCHEMA || '_' || TG_TABLE_NAME || '_actividad';
END IF;
PERFORM creartablaactividad(TG_TABLE_SCHEMA, TG_TABLE_NAME);
l_sql := 'INSERT INTO actividad.%I SELECT current_user, current_timestamp, %L, ($1).*';
IF TG_OP = 'DELETE' THEN
execute format(l_sql, newtable, 'D') using OLD;
RETURN OLD;
ELSE
-- covers UPDATE and INSERT
execute format(l_sql, newtable, 'U') using NEW;
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
Utiliser des espaces réservés comme %I
et %L
permet également de définir le SQL réel une seule fois et de le réutiliser. Ces "paramètres" sont remplacés par le format()
fonction (qui conserve le $1
)
Notez l'utilisation de ($1).*
à l'intérieur de la chaîne SQL. Cela fera execute
instruction développer le paramètre d'enregistrement $1
à toutes ses colonnes. L'enregistrement lui-même est passé "nativement" avec le USING
mot-clé.
L'utilisation de INSERT
sans liste de colonnes cible (insert into some_table ...
au lieu de insert into some_table (col1, col2, ...) ...
) est une chose assez fragile à faire. Si la source et la cible ne correspondent pas, l'insertion peut échouer assez facilement. .
Si vous n'exécutez pas de rapports massifs sur les tables d'audit (où avoir des noms de colonnes explicites serait beaucoup plus efficace), vous voudrez peut-être penser à un déclencheur d'audit plus générique utilisant un JSON
ou HSTORE
colonne pour stocker l'intégralité de l'enregistrement. Plusieurs déclencheurs d'audit prêts à l'emploi sont disponibles :
- http://okbob.blogspot. de/2015/01/most-simply-implementation-of-history.html
- https://github.com/wingspan/wingspan-auditing
- https://www.cybertec-postgresql.com /fr/suivi-des-changements-dans-postgresql/
- https://wiki.postgresql.org/wiki/Audit_trigger_91plus