PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come utilizzare le impostazioni delle variabili nelle funzioni di trigger?

Gestisci tutti i casi possibili per l'opzione personalizzata correttamente:

  1. opzione non ancora impostata

    Tutti i riferimenti ad esso sollevano un' eccezione , incluso current_setting() a meno che non venga chiamato con il secondo parametro missing_ok . Il manuale:

  2. opzione impostata su un valore letterale intero valido

  3. opzione impostata su un valore letterale intero non valido

  4. opzione reset (che si riduce a un caso speciale di 3. )

    Ad esempio, se imposti un'opzione personalizzata con SET LOCAL o set_config('myvars.user_id3', '55', true) , il valore dell'opzione viene ripristinato al termine della transazione. Esiste ancora , può essere referenziato, ma ora restituisce una stringa vuota ('' ) - che non può essere convertito in integer .

Errori evidenti nella tua demo a parte, devi prepararti per tutti e 4 i casi. Quindi:

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<>violino qui

Note:

  • Evita i nomi delle variabili che corrispondono ai nomi delle colonne. Molto incline agli errori. Una convenzione di denominazione popolare è quella di anteporre i nomi delle variabili con un trattino basso:_user_id .

  • Assegna al momento della dichiarazione per salvare un'assegnazione. Nota il tipo di dati text . Trasmetteremo più tardi, dopo aver risolto l'input non valido.

  • Evita di sollevare/intrappolare un'eccezione se possibile . Il manuale:

  • Verifica la presenza di stringhe intere valide. Questa semplice espressione regolare consente solo cifre (nessun segno iniziale, nessuno spazio bianco):_user_id ~ '^\d+$' . Ho ripristinato su NULL per qualsiasi input non valido. Adattati alle tue esigenze.

  • Ho aggiunto un WARNING opzionale per comodità di debug.

  • Casi 3. e 4. sorgono solo perché le opzioni personalizzate sono stringhe letterali (digitare text ), i tipi di dati validi non possono essere applicati automaticamente.

Correlati:

A parte questo, potrebbero esserci soluzioni più eleganti per ciò che stai cercando di fare senza opzioni personalizzate, a seconda delle tue esatte esigenze. Forse questo: