PG中的NULL是不能用于比较的,也不能用于运算操作等。
SELECT NULL != 'abc'; – 这个返回NULL
SELECT NULL = 'abc' ; – 同样返回NULL
SELECT NULL = NULL; – 还是返回NULL
注意,这里返回的是NULL,不是true/false。这说明PG的NULL是不能用于比较的。
再看一段PG与Sybase的NULL使用对比。
![]()
|
![]()
|
下面介绍两个在我们CP8项目中遇到过的由NULL引起的issues。
案例一. NULL导致AWS SCT没有正确转换Sybase代码
下面原Sybase代码,其功能就是当v为null时,返回value1,否则,返回value2
case v when null then value1 else value2 end
AWS SCT转换后的PG代码:
CASE v WHEN NULL THEN value1 ELSE value2 END
可以看出,除了大小写不同外,其它没有变化。但这代码在PG中运行是有问题的,不管v是否为NULL,都会返回value2。
正确的做法是使用IS NULL子句,因此PG正确的代码应该是:
CASE WHEN v is NULL THEN value1 ELSE value2 END
(本案例由Wick发现并解决)
所以,在PG中,可以使用IS NULL和IS NOT NULL来显式地检查NULL值,但不能直接使用比较运算符(=,!=)进行性判断。
案例二. NULL导致用字符串连接失败
看下面的SQL,功能是将两个字符串连接起来,其中var1和var2是varchar变量:
var2 := 'value=' || var1;
当var1非NULL时,这个代码是能正常运行的;但当var1为NULL时,这行代码就崩溃了,var2 被赋值为NULL。这是因为PG认为NULL不能参与运算操作。在PG中,正确的赋值方法是使用concat函数:
var2 := concat('value=', var1); -- 这个返回 “value=”,
或使用coalesce函数
var2 := 'value=' || coalesce(var1, 'NULL'); -- 这个返回 ”value=NULL“
重新认识PG中NULL,可以帮助我们编写正确的SQL代码。
:重新认识NULL/3570845679.png)
:重新认识NULL/2023264337.png)