J'écris un déclencheur de validation. Le déclencheur doit valider que la somme d'un tableau est égale à un autre champ. Étant donné que j'ai de nombreuses instances de cette validation, je veux écrire une seule procédure et créer plusieurs déclencheurs, chacun avec un ensemble différent de champs à vérifier.
Par exemple, j'ai le schéma suivant:
CREATE TABLE daily_reports(
start_on date
, show_id uuid
, primary key(start_on, show_id)
-- _graph are hourly values, while _count is total for the report
, impressions_count bigint not null
, impressions_graph bigint[] not null
-- interactions_count, interactions_graph
-- twitter_interactions_count, twitter_interactions_graph
);
La validation doit le confirmer impressions_count = sum(impressions_graph)
.
Je suis bloqué car je ne sais pas comment accéder dynamiquement à un champ depuis NEW
plpgsql:
CREATE FUNCTION validate_sum_of_array_equals_other() RETURNS TRIGGER AS $$
DECLARE
total bigint;
array_sum bigint;
BEGIN
-- TG_NARGS = 2
-- TG_ARGV[0] = 'impressions_count'
-- TG_ARGV[1] = 'impressions_graph'
-- How to access impressions_count and impressions_graph from NEW?
RETURN NEW;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER validate_daily_reports_impressions
ON daily_reports BEFORE INSERT OR UPDATE
FOR EACH ROW EXECUTE
validate_sum_of_array_equals_other('impressions_count', 'impressions_graph');
J'ai essayé d' exécuter des commandes dynamiques en faisant EXECUTE 'SELECT $1 FROM NEW' INTO total USING TG_ARGV[0]
, mais PL / PGsql se plaint que NEW est une relation inconnue.
Je cible spécifiquement PostgreSQL 9.1.
NEW
pour le moment est d'utiliser hstore(NEW)
puis d'accéder aux champs en tant que hstore
valeurs saisies par nom de colonne. Ce qui est nul, car ils sont tous castés text
et si vous souhaitez travailler avec eux dans leur type d'origine, vous devez les restituer. Alternativement, vous pouvez écrire un déclencheur dans un autre langage procédural comme PL / Python qui prend mieux en charge l'accès aux enregistrements dynamiques.