L'espressione stringexpression = ''
produce:
TRUE
.. per ''
(o per qualsiasi stringa costituita da soli spazi con il tipo di dati char(n)
)
NULL
.. per NULL
FALSE
.. per qualsiasi altra cosa
Quindi per verificare: " stringexpression
è NULL o vuoto" :
(stringexpression = '') IS NOT FALSE
Oppure l'approccio inverso (potrebbe essere più facile da leggere):
(stringexpression <> '') IS NOT TRUE
Lavora per qualsiasi tipo di carattere incluso char(n)
. Il manuale sugli operatori di confronto.
O usa la tua espressione originale senza trim()
, che è costoso rumore per char(n)
(vedi sotto), o errata per altri tipi di caratteri: le stringhe costituite solo da spazi passerebbero come stringa vuota.
coalesce(stringexpression, '') = ''
Ma le espressioni in alto sono più veloci.
Affermare il contrario è ancora più semplice: "stringexpression
non è né NULL né vuoto" :
stringexpression <> ''
Questo è circa il tipo di dati char(n)
, abbreviazione di: character(n)
. ( char
/ character
sono l'abbreviazione di char(1)
/ character(1)
.) Il suo utilizzo è sconsigliato in Postgres :
Nella maggior parte delle situazioni text
o character varying
dovrebbe essere usato invece.
Non confondere char(n)
con altri utili, tipo, carattere varchar(n)
, varchar
,text
o"char"
(con virgolette).
In char(n)
una stringa vuota non è diverso da qualsiasi altra stringa costituita da soli spazi. Tutti questi sono piegati in n spazi char(n)
per definizione del tipo. Segue logicamente che le espressioni precedenti funzionano perchar(n)
- proprio come queste (che non funzionerebbero con altri tipi di caratteri):
coalesce(stringexpression, ' ') = ' '
coalesce(stringexpression, '') = ' '
dimostrazione
La stringa vuota è uguale a qualsiasi stringa di spazi quando viene lanciata su char(n)
:
SELECT ''::char(5) = ''::char(5) AS eq1
, ''::char(5) = ' '::char(5) AS eq2
, ''::char(5) = ' '::char(5) AS eq3;
Risultato:
eq1 | eq2 | eq3
----+-----+----
t | t | t
Test per "stringa nulla o vuota" con 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);
Risultato:
stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
pippo | 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
Test per "stringa nulla o vuota" con 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);
Risultato:
stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
pippo | 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 <> violino qui
Vecchio sqlfiddle
Relazionato:
char
è quasi sempre la scelta sbagliata a causa dell'imbottitura (e della conseguente perdita di spazio). Ma a parte questo: non penso che ci sia una soluzione migliore.