web-dev-qa-db-fra.com

Meilleur moyen de vérifier "valeur vide ou nulle"

Quel est le meilleur moyen de vérifier si la valeur est null ou une chaîne vide dans les instructions Postgres sql?

La valeur peut être une expression longue, il est donc préférable qu’elle ne soit écrite qu’une seule fois.

Actuellement, j'utilise:

coalesce( trim(stringexpression),'')=''

Mais ça a l'air un peu moche.

stringexpression peut être char(n) colonne ou expression contenant char(n) colonnes avec des espaces finaux.

Quel est le meilleur moyen?

138
Andrus

L'expression _stringexpression = ''_ donne:

TRUE .. pour _''_ (ou pour toute chaîne constituée uniquement d'espaces du type de données char(n))
NULL .. pour NULL
FALSE .. pour rien sinon

Donc, pour vérifier: "stringexpression est soit NULL, soit 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 la char(n) obsolescente qui n’est guère utile.
Le manuel sur les opérateurs de comparaison.

ou utilisez l'expression que vous aviez déjà, sans la trim() qui serait inutile pour char(n) (voir ci-dessous), ou inclure des chaînes composées uniquement d'espaces dans le test pour d'autres types de caractères:

_coalesce(stringexpression, '') = ''
_

Mais les expressions au sommet sont plus rapides.

Affirmant le contraire: "stringexpression n'est ni NULL ni vide" est encore plus simple:

_stringexpression <> ''
_

À propos de char(n)

Ne confondez pas ce type de données avec d'autres types de caractères tels que varchar(n), varchar, text OU _"char" (avec guillemets), qui sont tous des types de données utiles. Ceci concerne le type de données obsolète ayant une utilité très limitée: char(n), abréviation de: character(n). De plus, char et character sont l'abréviation de char(1)/character(1) (même chose).

Dans char(n) (contrairement aux autres types de chaînes!), Une chaîne vide ne diffère de aucune autre chaîne composée uniquement d'espaces. Tous ceux-ci sont pliés à n espaces dans char(n) selon la définition du type. Il s'ensuit logiquement que cela fonctionne pour char(n) également:

_coalesce(stringexpression, '') = ''
_

Autant que ceux-ci (qui ne fonctionneraient pas pour d'autres types de personnages):

_coalesce(stringexpression, '  ') = '  '
coalesce(stringexpression, '') = '       '
_

Démo

Une chaîne vide équivaut à une chaîne d'espaces lors de la conversion en char(n):

_SELECT ''::char(5) = ''::char(5)     AS eq1
      ,''::char(5) = '  '::char(5)   AS eq2
      ,''::char(5) = '    '::char(5) AS eq3;
_
_eq1 | eq2 | eq3
----+-----+----
t   | t   | t  
_

Testez "chaîne nulle ou vide" avec char(n):

_SELECT stringexpression 
      ,stringexpression = ''                    AS simple_test
      ,(stringexpression = '')  IS NOT FALSE    AS test1
      ,(stringexpression <> '') IS NOT TRUE     AS test2
      ,coalesce(stringexpression, '') = ''      AS test_coalesce1
      ,coalesce(stringexpression, '  ') = '  '  AS test_coalesce2
      ,coalesce(stringexpression, '') = '  '    AS test_coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , (NULL)
   , ('   ')                -- not different from '' in char(n)
   ) sub(stringexpression);
_
_ stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | t              | t
                  |             | t     | t     | t              | t              | t
                  | t           | t     | t     | t              | t              | t
_

Test de "chaîne nulle ou vide" avec text

_SELECT stringexpression 
      ,stringexpression = ''                    AS simple_test
      ,(stringexpression = '')  IS NOT FALSE    AS test1
      ,(stringexpression <> '') IS NOT TRUE     AS test2
      ,coalesce(stringexpression, '') = ''      AS test_coalesce1
      ,coalesce(stringexpression, '  ') = '  '  AS test_coalesce2
      ,coalesce(stringexpression, '') = '  '    AS test_coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , (NULL)
   , ('   ')                -- different from '' in a sane character type like text
   ) sub(stringexpression);
_
_ stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | f              | f
                  |             | t     | t     | t              | t              | f
                  | f           | f     | f     | f              | f              | f
_

dbfiddle ici
Old SQL Fiddle

Apparenté, relié, connexe:

232

Pour vérifier la valeur null et empty:

coalesce(string, '') = ''

Pour vérifier les valeurs nulles, vides et les espaces (couper la chaîne)

coalesce(TRIM(string), '') = ''
33
sam

La vérification de la longueur de la chaîne fonctionne également et est compacte:

where length(stringexpression) > 0;
2
yglodt

S'il peut y avoir des espaces vides, il n'y a probablement pas de meilleure solution. COALESCE est juste pour des problèmes comme le vôtre.

2
Świstak35

Quelque chose que j'ai vu les gens utiliser est stringexpression > ''. Ce n'est peut-être pas le plus rapide, mais se trouve être l'un des plus courts.

Essayé sur MS SQL ainsi que sur PostgreSQL.

1
TarasB

Si la base de données a un grand nombre d'enregistrements, alors null check peut prendre plus de temps, vous pouvez utiliser le contrôle nul de différentes manières, par exemple: 1) where columnname is null 2) where not exists() 3) WHERE (case when columnname is null then true end)

0
Ambrish Rajput

Ma méthode préférée pour comparer les champs nullables est la suivante: NULLIF (nullablefield,: ParameterValue) IS NULL ET NULLIF (: ParameterValue, nullablefield) IS NULL. C'est fastidieux, mais il est d'usage universel, tandis que Coalesce est impossible dans certains cas.

La deuxième et inverse utilisation de NULLIF est due au fait que "NULLIF (nullablefield,: ParameterValue) IS NULL" retournera toujours "true" si le premier paramètre est null.

0
Danilo da Silva