Eu vejo duas razões possíveis, por que ...
Nenhum desses aumentos aparece no meu log de mensagens
Não registrado
Em primeiro lugar, um
NOTICE
normalmente não é gravado no log do banco de dados com configurações padrão. Cito o manual aqui:
log_min_messages
(enum
)
Controla quais níveis de mensagem são gravados no log do servidor. Os valores válidos sãoDEBUG5
,DEBUG4
,DEBUG3
,DEBUG2
,DEBUG1
,INFO
,NOTICE
,NOTICE
,ERROR
,LOG
,FATAL
ePANIC
. (...)
O padrão é AVISO . Observe queLOG
tem uma classificação diferente aqui do que emclient_min_messages
.
Minha ênfase em negrito. Observe também o padrão diferente (
NOTICE
) para client_min_messages
(item anterior no manual). Teste inválido
Em segundo lugar, considere como uma expressão de linha é avaliada. Um teste
row_variable IS NULL
retorna TRUE
se (e somente se) todos os elementos é NULL
. Dado o seguinte exemplo:SELECT (1, NULL) IS NULL AS a -- FALSE
,(1, NULL) IS NOT NULL AS b -- also FALSE
Ambos expressões retornam
FALSE
. Em outras palavras, uma variável de linha (ou registro) (1, NULL)
não é NULL
, nem é NOT NULL
. Portanto, ambos os testes falham. -> SQLfiddle com mais detalhes.
Mais detalhes, explicação, links e uma possível aplicação para este comportamento em um
CHECK
restrição nesta resposta relacionada:NOT NULL constraint sobre um conjunto de colunas
Você pode até atribuir uma variável de registro com NULL (
rec := NULL
), o que resulta em cada elemento sendo NULL - se o tipo for um tipo de linha bem conhecido. Caso contrário, estamos lidando com um registro anônimo e a estrutura é indefinida e você não pode acessar os elementos para começar. Mas esse não é o caso de um rowtype
como no seu exemplo (que é sempre bem conhecido). Solução:FOUND
Qual é a maneira correta de testar se você recebeu uma linha de umSELECT * INTO
?
Você deve considerar que a linha pode ser NULL, mesmo que tenha sido atribuída. A consulta pode muito bem ter retornado vários valores NULL (se a definição da tabela em sua consulta permitir valores NULL). Tal teste não seria confiável por design.
Existe uma abordagem simples e segura. Use
GET DIAGNOSTICS ...
ou (quando aplicável) a variável especial FOUND
:SELECT * FROM my_table WHERE owner_id = 6 INTO my_var;
IF NOT FOUND THEN
RAISE NOTICE 'Query did not return a row!';
END IF;
Detalhes no manual.