PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment utiliser les paramètres de variables dans les fonctions de déclenchement ?

Gérez tous les cas possibles pour l'option personnalisée correctement :

  1. 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ètre missing_ok . Le manuel :

  2. option définie sur un littéral entier valide

  3. option définie sur un entier littéral invalide

  4. option reset (qui se réduit à un cas particulier de 3. )

    Par exemple, si vous définissez une option personnalisée avec SET LOCAL ou set_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é en integer .

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. et 4. surviennent uniquement parce que les options personnalisées sont des littéraux de chaîne (type text ), les types de données valides ne peuvent pas être appliqués automatiquement.

Connexe :

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 :