SQL的NULL踩坑记录
前几天写我的开源项目时,发现一个bug,不能正确获取文件名,debug后才发现有一条DQL有问题:
SELECT file_name FROM files
WHERE file_id = #{fileId}
AND webdav_path != 'deleted'
LIMIT 1
乍一看没什么问题,就是把字段file_id为fileId且字段webdav_path 不为‘delete’的找到的第一行查询出来,但是我debug后,发现这条DQL语句并没有按照我预期的查到数据,问了问GPT,才想起:NULL是一个未知状态,而非一个具体的值。
就是因为NULL并非一个具体的值,而且我的webdav_path字段允许为NULL,才导致webdav_path为NULL的我预期要查找到的值没能查到。
在 SQL 里,NULL
不是一个具体的值,而是“未知”状态,因此 NULL != 'deleted'
的比较结果不会是 TRUE
,而是 UNKNOWN
在 WHERE
子句里,只有 TRUE
的记录才会被选中,所以:
webdav_path = 'deleted'
的行不会被选中webdav_path IS NULL
的行不会被选中(因为NULL != 'deleted'
结果是UNKNOWN
)
知道了原因后,修复就简单了,只需要在条件里加上webdav_path IS NULL
SELECT file_name FROM files
WHERE file_id = #{fileId}
AND (webdav_path IS NULL OR webdav_path != 'deleted')
LIMIT 1