Lide com todos os casos possíveis para a opção personalizada devidamente:
-
opção ainda não definida
Todas as referências a ele geram uma exceção , incluindocurrent_setting()
a menos que seja chamado com o segundo parâmetromissing_ok
. O manual:
-
opção definida como um literal inteiro válido
-
opção definida como um literal inteiro inválido
-
opção reset (que se reduz a um caso especial de 3. )
Por exemplo, se você definir uma opção personalizada comSET LOCAL
ouset_config('myvars.user_id3', '55', true)
, o valor da opção é zerado ao final da transação. Ele ainda existe , pode ser referenciado, mas retorna uma string vazia agora (''
) - que não pode ser convertido eminteger
.
Erros óbvios em sua demonstração à parte, você precisa se preparar para todos os 4 casos. Então:
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 aqui
Notas:
-
Evite nomes de variáveis que correspondam aos nomes das colunas. Muito propenso a erros. Uma convenção de nomenclatura popular é preceder os nomes das variáveis com um sublinhado:_user_id
.
-
Atribua no momento da declaração para salvar uma atribuição. Observe o tipo de dadostext
. Faremos a conversão mais tarde, depois de classificar a entrada inválida.
-
Evite levantar/capturar uma exceção se possível . O manual:
-
Teste para strings inteiras válidas. Essa expressão regular simples permite apenas dígitos (sem sinal inicial, sem espaço em branco):_user_id ~ '^\d+$'
. Eu redefino para NULL para qualquer entrada inválida. Adapte-se às suas necessidades.
-
Adicionei umWARNING
opcional para sua conveniência de depuração.
-
Casos3.
e4.
só surgem porque as opções personalizadas são literais de string (tipotext
), os tipos de dados válidos não podem ser aplicados automaticamente.
Relacionado:
- Variáveis definidas pelo usuário no PostgreSQL
- Existe uma maneira de definir uma constante nomeada em uma consulta do PostgreSQL?
Deixando tudo isso de lado, pode haver soluções mais elegantes para o que você está tentando fazer sem opções personalizadas, dependendo de suas necessidades exatas. Talvez isto: