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

Value可以是一个很长的表达式,所以在检查时最好只写一次。

目前我正在使用:

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

但是看起来有点丑。

Stringexpression可以是char(n)列,也可以是包含char(n)列的表达式,后面带空格。

最好的方法是什么?


当前回答

检查是否为空:

coalesce(string, '') = ''

检查null, empty和空格(修剪字符串)

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

其他回答

如果后面可能有空的空格,可能没有更好的解决方案。COALESCE只是为了解决像你这样的问题。

我喜欢yglodt的答案,但对于大的集合和大的字符串来说,计算准确的长度可能是昂贵的,所以我选择:

coalesce(trim('a') > '','f')

表达式stringexpression = "得到:

真正的. .对于"(或任何仅由数据类型为char(n)的空格组成的字符串) 空. .为零 假. .还有其他的吗

所以要检查:"stringexpression is NULL or empty":

(stringexpression = '') IS NOT FALSE

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

(stringexpression <> '') IS NOT TRUE

适用于包括char(n)在内的任何字符类型。关于比较操作符的手册。

或者使用没有trim()的原始表达式,这对于char(n)是代价高昂的噪声(见下文),或者对于其他字符类型是不正确的:仅由空格组成的字符串将作为空字符串传递。

coalesce(stringexpression, '') = ''

但是顶部的表达式更快。

相反的断言甚至更简单:"stringexpression既不是NULL也不是empty":

stringexpression <> ''

关于char (n)

这是关于数据类型char(n),字符(n)的缩写。(char / character是char(1) / character(1)的缩写。)不鼓励在Postgres中使用:

在大多数情况下,应该使用文本或字符变化来代替。

不要将char(n)与其他有用的字符类型varchar(n)、varchar、text或“char”(带双引号)混淆。

在char(n)中,空字符串与其他仅由空格组成的字符串没有什么不同。所有这些都以char(n)为单位折叠成n个空格。从逻辑上讲,上面的表达式也适用于char(n)——就像这些表达式一样(不适用于其他字符类型):

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

Demo

空字符串在转换为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

测试“null或空字符串”与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 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | 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

测试“null或空字符串”文本:

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 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | 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 < >小提琴 老sqlfiddle

相关:

使用数据类型“文本”存储字符串的任何缺点?

另一种方法是

nullif(trim(stringExpression),'') is not null

我比较可空字段的首选方法是: NULLIF(nullablefield,:ParameterValue) IS NULL AND NULLIF(:ParameterValue, nullablefield) IS NULL。这很麻烦,但是通用的,而Coalesce在某些情况下是不可能的。

NULLIF的第二个反向使用是因为“NULLIF(nullablefield,:ParameterValue) is NULL”如果第一个参数为空,将总是返回“true”。