检查“空值或空值”的最佳方法


175

在Postgres sql语句中检查value是否为null或空字符串的最佳方法是什么?

值可以是长表达式,因此最好只在校验中写入一次。

目前,我正在使用:

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

但是看起来有点难看。

stringexpression可以是char(n)列或包含char(n)带有尾随空格的列的表达式。

最好的方法是什么?


3
char由于填充(以及由此造成的空间浪费),使用几乎总是错误的选择。但除此之外:我认为没有更好的解决方案。
a_horse_with_no_name 2014年

为什么丑?逻辑清晰。
klin

1
@a_horse_with_no_name:我认为是。
Erwin Brandstetter,2014年

Answers:


281

表达式stringexpression = ''产生:

TRUE   .. for ''(或仅由数据类型   为空格的任何字符串组成char(n)
NULL.. for NULL
FALSE ..其他

因此要检查:stringexpression是NULL还是空”

(stringexpression = '') IS NOT FALSE

或相反的方法(可能更容易阅读):

(stringexpression <> '') IS NOT TRUE

适用于任何字符类型,包括char(n)关于比较运算符的手册。

使用不带的原始表达式trim(),这会带来很大的麻烦char(n)(请参阅下文),或者对于其他字符类型而言是不正确的:仅包含空格的字符串将作为空字符串传递。

coalesce(stringexpression, '') = ''

但是顶部的表达式更快。

声明相反的结果甚至更简单:stringexpression既不是NULL也不为空”

stringexpression <> ''

关于 char(n)

这与数据类型有关char(n),简称:character(n)。(char/ character短为char(1)/ character(1)。)它的使用在Postgres的泄气

在大多数情况下text还是character varying应该代替使用。

不要混淆char(n)与其他的,有用的,字符类型varchar(n)varchartext"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);

结果:

stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | 合并3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 foo | f | f | f | f | f | F
                  | t | t | t | t | t | Ť
                  | t | t | t | t | t | Ť
               |        | t | t | t | t | Ť

使用以下命令测试“空字符串或空字符串” 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);

结果:

stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | 合并3
------------------ + ----------- + ------- + ------- + --- -------- + ----------- + -----------
 foo | f | f | f | f | f | F
                  | t | t | t | t | f | F
                  | f | f | f | f | f | F
               |        | t | t | t | t | F

db <> fiddle here
旧的sqlfiddle

有关:


2
@a_horse_with_no_name:OP要求输入best way to check if value is null or empty string。这个trim()电话(相对)昂贵-只是没有必要。我添加了更多有关char(n)“空字符串”的信息。
Erwin Brandstetter,2014年

1
您写道,任何仅包含空格的字符串表达式都等于''。我可以去除装饰并用于coalesce(stringexpression,'')=''检查吗?与您的答案相比,这对我而言更具可读性。
Andrus 2014年

1
@Andrus:是的,可以。我在答案中添加了更多内容。
Erwin Brandstetter,2014年

3
select coalesce(' ', '') = '' 返回false。因此需要TRIM()
Andrus 2014年

1
但是coalesce(' '::char(5), '') = ''没有。无论如何,我都会使用前两个表达式之一,这些表达式适用于任何字符类型,并且速度最快,最简洁。
Erwin Brandstetter,2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.