sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo usar la configuración de variables en las funciones de activación?

Manejar todos los casos posibles para la opción personalizada correctamente:

  1. opción aún no configurada

    Todas las referencias generan una excepción , incluido current_setting() a menos que se llame con el segundo parámetro missing_ok . El manual:

  2. opción establecida en un literal entero válido

  3. opción establecida en un literal entero no válido

  4. reinicio de opción (que se reduce a un caso especial de 3. )

    Por ejemplo, si establece una opción personalizada con SET LOCAL o set_config('myvars.user_id3', '55', true) , el valor de la opción se restablece al final de la transacción. Todavía existe , se puede hacer referencia, pero ahora devuelve una cadena vacía ('' ) - que no se puede convertir a integer .

Dejando a un lado los errores obvios en su demostración, debe prepararse para los 4 casos. Entonces:

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 aquí

Notas:

  • Evite nombres de variables que coincidan con nombres de columnas. Muy propenso a errores. Una convención de nomenclatura popular es anteponer un guión bajo a los nombres de las variables:_user_id .

  • Asigne en el momento de la declaración para guardar una asignación. Tenga en cuenta el tipo de datos text . Transmitiremos más tarde, después de clasificar la entrada no válida.

  • Evite generar/atrapar una excepción si es posible . El manual:

  • Prueba de cadenas enteras válidas. Esta expresión regular simple solo permite dígitos (sin signo inicial, sin espacios en blanco):_user_id ~ '^\d+$' . Restablecí a NULL para cualquier entrada no válida. Adáptate a tus necesidades.

  • Agregué una WARNING opcional para su comodidad de depuración.

  • Casos 3. y 4. solo surgen porque las opciones personalizadas son literales de cadena (escriba text ), los tipos de datos válidos no se pueden aplicar automáticamente.

Relacionado:

Aparte de todo eso, puede haber soluciones más elegantes para lo que está tratando de hacer sin opciones personalizadas, según sus requisitos exactos. Tal vez esto: