Gérez tous les cas possibles pour l'option personnalisée correctement :
-
option pas encore définie
Toutes les références à celui-ci génèrent une exception , y compris
current_setting()
sauf si appelé avec le second paramètremissing_ok
. Le manuel : -
option définie sur un littéral entier valide
-
option définie sur un entier littéral invalide
-
option reset (qui se réduit à un cas particulier de 3. )
Par exemple, si vous définissez une option personnalisée avec
SET LOCAL
ouset_config('myvars.user_id3', '55', true)
, la valeur de l'option est réinitialisée à la fin de la transaction. Il existe toujours , peut être référencé, mais il renvoie maintenant une chaîne vide (''
) - qui ne peut pas être casté eninteger
.
Mis à part les erreurs évidentes dans votre démo, vous devez vous préparer pour les 4 cas. Donc :
CREATE OR REPLACE FUNCTION add_transition1()
RETURNS trigger AS
$func$
DECLARE
_user_id text := current_setting('myvars.user_id', true); -- see 1.
BEGIN
IF _user_id ~ '^\d+$' THEN -- one or more digits?
INSERT INTO transitions1 (user_id, house_id)
VALUES (_user_id::int, NEW.id); -- valid int, cast is safe
ELSE
INSERT INTO transitions1 (user_id, house_id)
VALUES (NULL, NEW.id); -- use NULL instead
RAISE WARNING 'Invalid user_id % for house_id % was reset to NULL!'
, quote_literal(_user_id), NEW.id; -- optional
END IF;
RETURN NULL; -- OK for AFTER trigger
END
$func$ LANGUAGE plpgsql;
db<>violon ici
Remarques :
-
Évitez les noms de variable qui correspondent aux noms de colonne. Très sujet aux erreurs. Une convention de nommage courante consiste à faire précéder les noms de variables d'un trait de soulignement :
_user_id
. -
Affecter au moment de la déclaration pour enregistrer une affectation. Notez le type de données
text
. Nous diffuserons plus tard, après avoir trié les entrées non valides. -
Éviter de déclencher/piéger une exception si possible . Le manuel :
-
Teste les chaînes d'entiers valides. Cette expression régulière simple n'autorise que les chiffres (pas de signe avant-coureur, pas d'espace blanc) :
_user_id ~ '^\d+$'
. Je réinitialise à NULL pour toute entrée invalide. Adaptez-vous à vos besoins. -
J'ai ajouté un
WARNING
facultatif pour votre commodité de débogage. -
Cas
3.
et4.
surviennent uniquement parce que les options personnalisées sont des littéraux de chaîne (typetext
), les types de données valides ne peuvent pas être appliqués automatiquement.
Connexe :
- Variables définies par l'utilisateur dans PostgreSQL
- Existe-t-il un moyen de définir une constante nommée dans une requête PostgreSQL ?
Tout cela mis à part, il peut y avoir des solutions plus élégantes pour ce que vous essayez de faire sans options personnalisées, en fonction de vos besoins exacts. Peut-être ceci :