我正在为我的MVC项目查询Oracle数据库,我在SQL中找到了一些我很好奇的东西。为什么此Query不返回VALIDATED_BY列为NULL的行?
SELECT *
FROM DM_SSA_DEV.REQUESTS
WHERE BATCH_ID = 1399
AND VALIDATED_BY <> 'AUTOUSER'
当我评论最后一行时,我得到了预期的481结果:
SELECT *
FROM DM_SSA_DEV.REQUESTS
WHERE BATCH_ID = 1399
--AND VALIDATED_BY <> 'AUTOUSER'
最后,我发现我可以通过显式处理NULL来绕过这个问题。这是正确的做法还是有更好的方法,为什么?
SELECT *
FROM DM_SSA_DEV.REQUESTS
WHERE BATCH_ID = 1399
AND (VALIDATED_BY <> 'AUTOUSER' OR VALIDATED_BY IS NULL)
P.S。我也在我的项目中使用Linq,所以这是我使用的代码。效率最高?
db.REQUESTS.Where(r => r.BATCH_ID == batchId && (r.VALIDATED_BY != "AUTOUSER" || r.VALIDATED_BY == NULL)).ToList<REQUEST>();
答案 0 :(得分:7)
NULL 永远不会等于(=
)任何其他值,甚至是另一个NULL(它有点像浮点NaN)。这还包括 not 涉及NULL的相等表达式。
当要将NULL值视为相等时,意图可以表示为x = y OR (y IS NULL and x IS NULL)
。
不等于或NULL且不相等的特殊情况是x <> y OR x IS NULL
,假设y永远不为NULL。
另一种选择是合并COALESCE(x, '*') = COALESCE(y, '*')
,具体取决于优化程序可信任的程度以及合并值与NULL的相等性。可能还有其他供应商扩展。
LINQ / EF会将x == null
(C#,null必须是常量表达式)转换为x IS NULL
(SQL)。