it-swarm.com.de

Der beste Weg, um nach "leeren oder leeren Werten" zu suchen

Wie kann am besten überprüft werden, ob der Wert in Postgres-SQL-Anweisungen null oder eine leere Zeichenfolge ist?

Der Wert kann ein langer Ausdruck sein. Es ist daher vorzuziehen, dass er nur einmal in check geschrieben wird.

Derzeit verwende ich:

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

Aber es sieht ein bisschen hässlich aus.

stringexpression kann eine char(n) Spalte oder ein Ausdruck sein, der char(n) Spalten mit nachgestellten Leerzeichen enthält.

Was ist der beste Weg?

138
Andrus

Der Ausdruck stringexpression = '' Ergibt:

TRUE .. für '' (oder für any Zeichenfolge, die nur aus Leerzeichen mit dem Datentyp char(n) besteht)
NULL .. für NULL
FALSE .. für irgendetwas sonst

Überprüfen Sie also, ob: "stringexpression entweder NULL oder leer ist":

(stringexpression = '') IS NOT FALSE

Oder der umgekehrte Ansatz (möglicherweise besser lesbar):

(stringexpression <> '') IS NOT TRUE

Funktioniert für jeder Zeichentyp einschließlich der veralteten char(n), die kaum jemals nützlich ist.
Das Handbuch zu Vergleichsoperatoren.

Oder Verwenden Sie den Ausdruck, den Sie bereits hatten, nur ohne die trim(), die für nutzlos wäre char(n) (siehe unten), oder es würde Zeichenfolgen enthalten, die nur aus Leerzeichen im Test für andere Zeichentypen bestehen:

coalesce(stringexpression, '') = ''

Aber die Ausdrücke oben sind schneller.

Das Gegenteil behaupten: "stringexpression ist weder NULL noch leer" ist noch einfacher:

stringexpression <> ''

Über char(n)

Verwechseln Sie diesen Datentyp nicht mit anderen Zeichentypen wie varchar(n), varchar, text oder "char" (mit Anführungszeichen) Dies sind alles nützliche Datentypen. Hierbei handelt es sich um den veralteten Datentyp mit sehr eingeschränkter Nützlichkeit: char(n), kurz für: character(n). Außerdem stehen char und character für char(1)/character(1) (dasselbe).

In char(n) (im Gegensatz zu anderen String-Typen!) Unterscheidet sich ein leerer String nicht von einem anderen String, der nur aus Leerzeichen besteht. Alle diese werden nach Definition des Typs zu n Leerzeichen in char(n) gefaltet. Logischerweise funktioniert dies auch für char(n):

coalesce(stringexpression, '') = ''

Genau so viel wie diese (was für andere Charaktertypen nicht funktionieren würde):

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

Demo

Eine leere Zeichenfolge entspricht einer Leerzeichenfolge, wenn sie in char(n) umgewandelt wird:

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  

Teste mit char(n) auf "null oder leere Zeichenkette":

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 auf "null oder leere Zeichenkette" mit 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 hier
Alte SQL-Geige

Verbunden:

232

So suchen Sie nach null und leer:

coalesce(string, '') = ''

So suchen Sie nach Nullen, Leerzeichen und Leerzeichen (kürzen Sie die Zeichenfolge)

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

Das Überprüfen der Länge der Zeichenfolge funktioniert ebenfalls und ist kompakt:

where length(stringexpression) > 0;
2
yglodt

Wenn möglicherweise nachgestellte Leerzeichen vorhanden sind, gibt es wahrscheinlich keine bessere Lösung. COALESCE ist nur für Probleme wie Ihres.

2
Świstak35

Etwas, das ich gesehen habe, ist stringexpression > ''. Dies ist möglicherweise nicht die schnellste, aber zufällig eine der kürzesten.

Versuchte es auf MS SQL sowie auf PostgreSQL.

1
TarasB

Wenn die Datenbank eine große Anzahl von Datensätzen enthält, kann null check Länger dauern. Sie können die Nullprüfung auf verschiedene Arten verwenden: 1) where columnname is null 2) where not exists() 3) WHERE (case when columnname is null then true end)

0
Ambrish Rajput

Mein bevorzugter Weg, nullbare Felder zu vergleichen, ist: NULLIF (nullablefield,: ParameterValue) IS NULL AND NULLIF (: ParameterValue, nullablefield) IS NULL. Dies ist umständlich ist aber universell einsetzbar, während Coalesce in einigen Fällen unmöglich ist.

Die zweite und umgekehrte Verwendung von NULLIF ist, weil "NULLIF (nullablefield,: ParameterValue) IS NULL" immer "true" zurückgibt, wenn der erste Parameter null ist.

0
Danilo da Silva