A expressão stringexpression = ''
produz:
TRUE
.. for ''
(ou para qualquer sequência que consiste apenas em espaços com o tipo de dados char(n)
)
NULL
.. forNULL
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 personagem, incluindo char(n)
. O manual sobre operadores de comparação.
Ou use sua expressão original sem trim()
, que é um ruído dispendioso para char(n)
(veja abaixo) ou incorreta para outros tipos de caracteres: cadeias que consistem em apenas espaços passariam como cadeias vazias.
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 <> ''
Isto é sobre o tipo de dados char(n)
, abreviação de: character(n)
. ( char
/ character
é a abreviação 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 confundir char(n)
com tipos de outro, útil, caráter varchar(n)
, varchar
, text
ou"char"
(com aspas).
Em char(n)
uma cadeia vazia não é diferente de qualquer outra cadeia que consiste apenas em espaços. Todos esses itens são dobrados em n espaços, char(n)
por definição do tipo. Segue-se logicamente que as expressões acima funcionam char(n)
também - exatamente como essas (que não funcionariam para outros tipos de caracteres):
coalesce(stringexpression, ' ') = ' '
coalesce(stringexpression, '') = ' '
Demo
Cadeia vazia é igual a qualquer cadeia 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 "cadeia 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:
expressão de cadeia | base_test | teste1 | teste2 | 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 "cadeia 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:
expressão de cadeia | base_test | teste1 | teste2 | 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 <> mexe aqui
Old sqlfiddle
Palavras-chave:
char
é quase sempre a escolha errada devido ao preenchimento (e ao desperdício de espaço resultante). Mas além disso: não acho que exista uma solução melhor.