我认为您在将 SQL 与 Java(或 C、C++ 或任何处理引用或指针的语言)进行比较时会产生误解。
在使用 SQL 时,您不需要需要保护条件表达式免受NULL 值的影响。
在 SQL 中,您没有(隐藏的)指向应该针对 NULL 进行测试的对象的指针(或引用),否则它们不能被取消引用。在 SQL 中,每个表达式都会产生某个 type 的某个 value。该值可以是NULL(也称为UNKNOWN)。
如果您的var 是NULL,那么var = 0 将评估为NULL(unknown = 0 返回 unknown)。然后var IS NULL (unknown is unknown) 将评估为TRUE。而且,根据三值逻辑,TRUE or UNKNOWN 的计算结果为TRUE。不管是哪种求值顺序,结果都是一样的。
你可以通过评估来检查它:
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
;
返回
null_equals_zero | null_is_null | true_or_null | your_case_when_var_is_null | the_same_reordered
:--------------- | :----------- | :----------- | :------------------------- | :-----------------
空 |吨 |吨 |吨 |吨
dbfiddle here
给定var = 0, NULL 和 1 ( 0);你会得到:
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 ;
变量 | var_equals_zero_or_var_is_null | var_is_null_or_var_equals_zero | the_same_with_protection
---: | :----------------------------- | :----------------------------- | :------------------------
0 |吨 |吨 |吨
空 |吨 |吨 |吨
1 | f | f | F
dbfiddle here
这些是使用three-valued logic 的不同运算符(NOT、AND、OR、IS NULL、XOR、IMPLIES)的基本真值表,并使用 SQL 进行检查:
WITH three_values(x) AS
(
VALUES
(NULL), (FALSE), (TRUE)
)
SELECT
a, b,
a = NULL AS a_equals_null, -- This is alwaus NULL
a IS NULL AS a_is_null, -- This is NEVER NULL
a OR b AS a_or_b, -- This is UNKNOWN if both are
a AND b AS a_and_b, -- This is UNKNOWN if any is
NOT a AS not_a, -- This is UNKNOWN if a is
(a OR b) AND NOT (a AND b) AS a_xor_b, -- Unknown when any is unknown
/* (a AND NOT b) OR (NOT a AND b) a_xor_b_v2, */
NOT a OR b AS a_implies_b -- Kleener and Priests logic
FROM
three_values AS x(a)
CROSS JOIN
three_values AS y(b);
这是真值表:
一个 |乙 | a_equals_null | a_is_null | a_or_b | a_and_b | not_a | a_xor_b | a_implies_b
:--- | :--- | :------------ | :-------- | :----- | :-------- | :---- | :-------- | :----------
空 |
空 |
空 |吨 |
空 |
空 |
空 |
空 |
空
空 | f |
空 |吨 |
空 | f |
空 |
空 |
空
空 |吨 |
空 |吨 |吨 |
空 |
空 |
空 |吨
f |
空 |
空 | f |
空 | f |吨 |
空 |吨
f | f |
空 | f | f | f |吨 | f |吨
f |吨 |
空 | f |吨 | f |吨 |吨 |吨
吨 |
空 |
空 | f |吨 |
空 | f |
空 |
空
吨 | f |
空 | f |吨 | f | f |吨 | F
吨 |吨 |
空 | f |吨 |吨 | f | f |吨
dbfiddle here