SQL的NULL踩坑记录

11 天前
/ , ,
5

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

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...