断言 1
连接运算符||
可以连接任何字符串类型的值,返回text
. 在 Postgres 中,每种类型都有一个文本表示,并且可以转换为text
. 因此,引用手册:
但是,字符串连接运算符 (
||
) 仍然接受非字符串输入,只要至少一个输入是字符串类型
有关的:
断言 2
连接一个或多个NULL
值会产生结果NULL
。
test=# SELECT (text 'foo' || NULL) IS NULL
test-# , (text 'bar' || char '1' || NULL ) IS NULL
test-# , (NULL::bigint || text 'baz') IS NULL;
?column? | ?column? | ?column?
----------+----------+----------
t | t | t
问题
是否可以连接 atext
和一个NULL
值并获得非空结果?
换句话说,这怎么可能?
test=# SELECT col IS NULL AS col_is_null
test-# , (text 'foo' || col) IS NULL AS result_is_null
test-# FROM tbl;
col_is_null | result_is_null
-------------+----------------
t | f
适用于任何 Postgres 版本。
我的一个客户偶然发现了这个,依靠结果是NULL
,我发现它很有趣,可以分享。
这是一个有点技巧的问题,因为我知道答案。
注意: CASE
或COALESCE
捕捉NULL
值通常是好的风格,但这不是这个问题的目的。这是关于与实际NULL
值的连接,使用连接运算符||
并且仍然得到非空结果。
那是因为 PostgreSQL 中的 CAST 数组类型系统有点奇怪(乍一看):-)
text || text[]
使双方都被强制为数组。另一个可能更能说明问题的例子:
Question Is it possible to concatenate a text and a NULL value and get a non-null result?
回答,是的!
使用嵌套
CASE
语句(感谢Craig Ringer):询问:
结果(
'*_
和'_*'
是为了更清楚地看到发生了什么!):