Обработка на всички възможни случаи за персонализирана опция правилно:
-
опцията все още не е зададена
Всички препратки към него водят до изключение , включително
current_setting()
освен ако не е извикан с втория параметърmissing_ok
. Ръководството: -
опция, зададена на валиден литерал на цяло число
-
опция, зададена на невалиден цялочислен литерал
-
нулиране на опция (което се записва до специален случай на 3. )
Например, ако зададете персонализирана опция с
SET LOCAL
илиset_config('myvars.user_id3', '55', true)
, стойността на опцията се нулира в края на транзакцията. Все още съществува , може да бъде препратен, но сега връща празен низ (''
) - което не може да бъде преобразувано вinteger
.
Като оставим настрана очевидните грешки във вашата демонстрация, трябва да се подготвите за всичките 4 случая. И така:
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 тук
Бележки:
-
Избягвайте имена на променливи, които съответстват на имена на колони. Много податливи на грешки. Една популярна конвенция за именуване е имената на променливите да се добавят с долна черта:
_user_id
. -
Присвояване по време на деклариране, за да запазите едно присвояване. Обърнете внимание на типа данни
text
. Ще кастираме по-късно, след като сортираме невалидните въведени данни. -
Избягвайте повдигане/прихващане на изключение, ако е възможно . Ръководството:
-
Тествайте за валидни низове с цели числа. Този прост регулярен израз позволява само цифри (без водещ знак, без бяло пространство):
_user_id ~ '^\d+$'
. Нулирам до NULL за всеки невалиден вход. Адаптирайте се към вашите нужди. -
Добавих незадължително
WARNING
за ваше удобство при отстраняване на грешки. -
Случаи
3.
и4.
възникват само защото персонализираните опции са низови литерали (типtext
), валидните типове данни не могат да бъдат наложени автоматично.
Свързани:
- Потребителски дефинирани променливи в PostgreSQL
- Има ли начин да се дефинира наименувана константа в заявка на PostgreSQL?
Всичко това настрана, може да има по-елегантни решения за това, което се опитвате да правите без персонализирани опции, в зависимост от вашите точни изисквания. Може би това: