在使用Postgresql多年之后,我仍然不知道是否存在关于如何保护条件表达式免受变量空值的最佳实践,因为SQL查询规划者具有应用或忽略的完全权限最常用的习惯用语来保护空值:" var为null或var = 0"。
据称,当......结束时使用'语法解决了任何歧义,但也降低了可维护性,因为它用大量单词模糊了一个简单的过程。
提前谢谢。
答案 0 :(得分:1)
我认为你比较SQL和Java(或C,C ++或任何处理引用或指针的语言)会产生误解。
使用SQL时,
在SQL中,您没有(隐藏)指向应该针对NULL测试的对象的指针(或引用),否则它们不能被解除引用。在SQL中,每个表达式都会生成某个类型的某个值。此值可以是NULL
(也称为NULL
)。
如果您的UNKNOWN
为var
,那么NULL
将评估为var = 0
(未知 = 0会返回 unknown )。然后NULL
(未知 未知)将评估为var IS NULL
。并且,根据三值逻辑,TRUE
评估为TRUE or UNKNOWN
。无论哪个是评估顺序,结果总是一样的。
您可以通过评估来检查:
TRUE
返回
null_equals_zero | null_is_null | true_or_null | your_case_when_var_is_null | the_same_reordered :--------------- | :----------- | :----------- | :------------------------- | :----------------- null | t | t | t | t
dbfiddle here
给定SELECT
/* var */ NULL = 0 as null_equals_zero,
/* var */ NULL IS NULL as null_is_null,
TRUE or NULL AS true_or_null,
(NULL = 0) OR (NULL IS NULL) AS your_case_when_var_is_null,
(NULL IS NULL) OR (NULL = 0) AS the_same_reordered
;
= 0,NULL和1(<> 0);你会得到:
var
var | var_equals_zero_or_var_is_null | var_is_null_or_var_equals_zero | the_same_with_protection ---: | :----------------------------- | :----------------------------- | :----------------------- 0 | t | t | t null | t | t | t 1 | f | f | f
dbfiddle here
这些是使用three-valued logic的不同运算符(NOT,AND,OR,IS NULL,XOR,IMPLIES)的基本真值表,并使用SQL检查:
WITH vals(var) AS
(
VALUES
(0),
(NULL),
(1)
)
SELECT
var,
var = 0 OR var IS NULL AS var_equals_zero_or_var_is_null,
var IS NULL OR var = 0 AS var_is_null_or_var_equals_zero,
CASE WHEN var IS NULL then true
WHEN var = 0 then true
ELSE false
END AS the_same_with_protection
FROM
vals ;
这是真相表:
a | b | a_equals_null | a_is_null | a_or_b | a_and_b | not_a | a_xor_b | a_implies_b :--- | :--- | :------------ | :-------- | :----- | :------ | :---- | :------ | :---------- null | null | null | t | null | null | null | null | null null | f | null | t | null | f | null | null | null null | t | null | t | t | null | null | null | t f | null | null | f | null | f | t | null | t f | f | null | f | f | f | t | f | t f | t | null | f | t | f | t | t | t t | null | null | f | t | null | f | null | null t | f | null | f | t | f | f | t | f t | t | null | f | t | t | f | f | t
dbfiddle here
答案 1 :(得分:0)
我似乎只问了一个永远存在的问题。因此,根据SQL逻辑表达式中的NULL传播问题,以及sql优化器不遵守短路结构以及不断发展SQL标准的危险,让我分享到目前为止我发现的内容: