PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie verwende ich variable Einstellungen in Triggerfunktionen?

Behandeln Sie alle möglichen Fälle für die benutzerdefinierte Option richtig:

  1. Option noch nicht gesetzt

    Alle Verweise darauf lösen eine Ausnahme aus , einschließlich current_setting() sofern nicht mit dem zweiten Parameter missing_ok aufgerufen . Das Handbuch:

  2. Option auf ein gültiges Integer-Literal gesetzt

  3. Option auf ein ungültiges Integer-Literal gesetzt

  4. Option reset (was auf einen Sonderfall von 3. hinausläuft )

    Zum Beispiel, wenn Sie eine benutzerdefinierte Option mit SET LOCAL setzen oder set_config('myvars.user_id3', '55', true) , wird der Optionswert am Ende der Transaktion zurückgesetzt. Es existiert noch , kann referenziert werden, gibt aber jetzt einen leeren String zurück ('' ) - die nicht in integer umgewandelt werden können .

Abgesehen von offensichtlichen Fehlern in Ihrer Demo müssen Sie sich auf alle 4 Fälle vorbereiten. Also:

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<>fiddle hier

Hinweise:

  • Vermeiden Sie Variablennamen, die mit Spaltennamen übereinstimmen. Sehr fehleranfällig. Eine beliebte Namenskonvention besteht darin, Variablennamen einen Unterstrich voranzustellen:_user_id .

  • Weisen Sie zum Zeitpunkt der Deklaration zu, um eine Zuordnung zu speichern. Beachten Sie den Datentyp text . Wir werden später umwandeln, nachdem ungültige Eingaben aussortiert wurden.

  • Vermeiden Sie das Auslösen/Abfangen einer Ausnahme wenn möglich . Das Handbuch:

  • Test auf gültige Integer-Strings. Dieser einfache reguläre Ausdruck erlaubt nur Ziffern (kein führendes Zeichen, kein Leerzeichen):_user_id ~ '^\d+$' . Ich setze für jede ungültige Eingabe auf NULL zurück. An Ihre Bedürfnisse anpassen.

  • Ich habe eine optionale WARNING hinzugefügt für Ihren Komfort beim Debuggen.

  • Fälle 3. und 4. treten nur auf, weil benutzerdefinierte Optionen Zeichenfolgenliterale sind (Typ text ), können gültige Datentypen nicht automatisch erzwungen werden.

Verwandte:

Abgesehen davon gibt es je nach Ihren genauen Anforderungen möglicherweise elegantere Lösungen für das, was Sie ohne benutzerdefinierte Optionen erreichen möchten. Vielleicht das: