PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Melhor maneira de verificar o valor vazio ou nulo


A expressão stringexpression = '' rendimentos:

TRUE .. para '' (ou para qualquer string consistindo apenas de espaços com o tipo de dados char(n) )
NULL .. para NULL
FALSE .. para qualquer outra coisa

Portanto, para verificar:"stringexpression é NULL ou vazio" :
(stringexpression = '') IS NOT FALSE

Ou a abordagem inversa (pode ser mais fácil de ler):
(stringexpression <> '') IS NOT TRUE

Funciona para qualquer tipo de caractere, incluindo char(n) . O manual sobre operadores de comparação.

Ou use sua expressão original sem trim() , que é um ruído caro para char(n) (veja abaixo), ou incorreto para outros tipos de caracteres:strings consistindo apenas de espaços passariam como string vazia.
coalesce(stringexpression, '') = ''

Mas as expressões no topo são mais rápidas.

Afirmar o contrário é ainda mais simples:"stringexpression não é NULL nem vazio" :
stringexpression <> ''

Sobre char(n)


Trata-se do tipo de dados char(n) , abreviação de:character(n) . (char / character são abreviações de char(1) / character(1) .) Seu uso é desencorajado no Postgres:

Na maioria das situações text ou character varying deve ser usado em seu lugar.

Não confunda char(n) com outros tipos de caracteres úteis varchar(n) , varchar , text ou "char" (com aspas duplas).

Em char(n) uma cadeia vazia não é diferente de qualquer outra string consistindo apenas de espaços. Todos estes são dobrados para n espaços em char(n) por definição do tipo. Segue logicamente que as expressões acima funcionam para char(n) também - tanto quanto estes (o que não funcionaria para outros tipos de caracteres):
coalesce(stringexpression, '  ') = '  '
coalesce(stringexpression, '') = '       '

Demonstração


A string vazia é igual a qualquer string de espaços quando convertida para char(n) :
SELECT ''::char(5) = ''::char(5)     AS eq1
     , ''::char(5) = '  '::char(5)   AS eq2
     , ''::char(5) = '    '::char(5) AS eq3;

Resultado:
 eq1 | eq2 | eq3
 ----+-----+----
 t   | t   | t

Teste para "string nula ou vazia" com char(n) :
SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);

Resultado:
 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | t         | t
                  | t         | t     | t     | t         | t         | t
 null             | null      | t     | t     | t         | t         | t

Teste para "string nula ou vazia" com text :
SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in a sane character types
   , (NULL)
   ) sub(stringexpression);

Resultado:
 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | f         | f
                  | f         | f     | f     | f         | f         | f
 null             | null      | t     | t     | t         | t         | f

db<>mexa aqui
antigo sqlfiddle

Relacionado:
  • Alguma desvantagem de usar o tipo de dados "texto" para armazenar strings?