Вираз stringexpression = ''
отримує:
TRUE
.. для ''
(або для будь-якого рядка, що складається лише з пробілів з типом даних char(n)
)
NULL
.. для NULL
FALSE
.. для всього іншого
Отже, щоб перевірити: " stringexpression
це NULL або порожній" :
(stringexpression = '') IS NOT FALSE
Або зворотний підхід (може бути простішим для читання):
(stringexpression <> '') IS NOT TRUE
Працює для будь-якого типу символів, включаючи char(n)
. Посібник про оператори порівняння.
Або використовуйте свій оригінальний вираз без trim()
, який є дорогим шумом char(n)
(див. Нижче), або невірним для інших типів символів: рядки, що складаються лише з пробілів, передаватимуться як порожній рядок.
coalesce(stringexpression, '') = ''
Але вирази вгорі швидші.
Стверджувати протилежне ще простіше: " stringexpression
не є ані NULL, ані порожнім" :
stringexpression <> ''
Йдеться про тип даних char(n)
, коротко для: character(n)
. ( char
/ character
короткі для char(1)
/ character(1)
.) Її використання не рекомендується використовувати в Postgres :
У більшості ситуацій text
або їх character varying
слід використовувати замість цього.
Не плутати char(n)
з типами інший, корисний характер varchar(n)
, varchar
, text
або"char"
(з подвійними лапками).
В char(n)
якості порожнього рядка не відрізняється від будь-якої іншої рядки , що складається тільки з прогалин. Все це складено на n пробілів у char(n)
відповідності з визначенням типу. Звідси логічно випливає, що вищезазначені вирази char(n)
також працюють - так само, як і ці (які не працюватимуть для інших типів символів):
coalesce(stringexpression, ' ') = ' '
coalesce(stringexpression, '') = ' '
Демо
Порожній рядок дорівнює будь-якому рядку пробілів при передачі на 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
Тест на "нуль або порожній рядок" за допомогою 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);
Результат:
строковий вираз | base_test | тест1 | тест2 | coalesce1 | coalesce2 | coalesce3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
foo | f | f | f | f | f | f
| т | т | т | т | т | т
| т | т | т | т | т | т
нульовий | нульовий | т | т | т | т | т
Тест на "нуль або порожній рядок" за допомогою 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);
Результат:
строковий вираз | base_test | тест1 | тест2 | coalesce1 | coalesce2 | coalesce3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
foo | f | f | f | f | f | f
| т | т | т | т | f | f
| f | f | f | f | f | f
нульовий | нульовий | т | т | т | т | f
db <> fiddle тут
Стара квадратна загадка
Пов'язані:
char
майже завжди є неправильним вибором через прокладки (і отримані в результаті космічні відходи). Але крім цього: я не думаю, що є кращого рішення.