Manejar todos los casos posibles para la opción personalizada correctamente:
-
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ámetromissing_ok
. El manual: -
opción establecida en un literal entero válido
-
opción establecida en un literal entero no válido
-
reinicio de opción (que se reduce a un caso especial de 3. )
Por ejemplo, si establece una opción personalizada con
SET LOCAL
oset_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 ainteger
.
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.
y4.
solo surgen porque las opciones personalizadas son literales de cadena (escribatext
), los tipos de datos válidos no se pueden aplicar automáticamente.
Relacionado:
- Variables definidas por el usuario en PostgreSQL
- ¿Hay alguna forma de definir una constante con nombre en una consulta de PostgreSQL?
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: