L'expression stringexpression = ''
donne:
TRUE
.. pour ''
(ou pour toute chaîne composée uniquement d'espaces avec le type de données char(n)
)
NULL
.. pour NULL
FALSE
.. pour tout le reste
Donc, pour vérifier: " stringexpression
est NULL ou vide" :
(stringexpression = '') IS NOT FALSE
Ou l'approche inverse (peut être plus facile à lire):
(stringexpression <> '') IS NOT TRUE
Fonctionne pour tout type de caractère, y compris char(n)
. Le manuel sur les opérateurs de comparaison.
Ou utilisez votre expression d'origine sans trim()
, ce qui est un bruit coûteux pour char(n)
(voir ci-dessous), ou incorrecte pour d'autres types de caractères: les chaînes constituées uniquement d'espaces passeraient comme une chaîne vide.
coalesce(stringexpression, '') = ''
Mais les expressions au sommet sont plus rapides.
Affirmer le contraire est encore plus simple: " stringexpression
n'est ni NULL ni vide" :
stringexpression <> ''
Ceci est sur le type de données char(n)
, abréviation de: character(n)
. ( char
/ character
sont des abréviations de char(1)
/ character(1)
.) Son utilisation est déconseillée dans Postgres :
Dans la plupart des situations text
ou character varying
devrait être utilisé à la place.
Ne pas confondre char(n)
avec d' autres, les types de caractères utiles varchar(n)
, varchar
,text
ou"char"
(avec guillemets).
Dans char(n)
une chaîne vide n'est pas différente de toute autre chaîne composée uniquement d'espaces. Tous ces éléments sont pliés en n espaces char(n)
par définition du type. Il s'ensuit logiquement que les expressions ci-dessus fonctionnent pourchar(n)
aussi bien - tout autant que celles-ci (qui ne fonctionneraient pas pour d'autres types de caractères):
coalesce(stringexpression, ' ') = ' '
coalesce(stringexpression, '') = ' '
Démo
Une chaîne vide équivaut à toute chaîne d'espaces lorsqu'elle est convertie en char(n)
:
SELECT ''::char(5) = ''::char(5) AS eq1
, ''::char(5) = ' '::char(5) AS eq2
, ''::char(5) = ' '::char(5) AS eq3;
Résultat:
eq1 | eq2 | eq3
----+-----+----
t | t | t
Teste la "chaîne nulle ou vide" avec 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);
Résultat:
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 la "chaîne nulle ou vide" avec 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);
Résultat:
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 <> violon ici
Ancien sqlfiddle
En relation:
char
est presque toujours le mauvais choix en raison du rembourrage (et du gaspillage d'espace qui en résulte). Mais à part ça: je ne pense pas qu'il y ait de meilleure solution.