今天碰到一个很奇怪的问题,开发的一个考试系统采用Access数据库作为题库,里面建了类似下面这样的临时表用于导入Excel格式的题库:
ID(自增,长整型) | 专业(文本) | 科目(文本) | 题型(文本) | 正文(备注) | 正文哈希(长整型) |
---|---|---|---|---|---|
1 | 计算机 | 数学 | 单选题 | AAA | FF |
2 | 计算机 | 数学 | 单选题 | BBB | CC |
3 | 信息工程 | 数学 | 单选题 | AAA | FF |
4 | 信息工程 | 数学 | 单选题 | CCC | DD |
先在Access 2007中创建了这样结构的一个空表,然后将Excel题库导入该表的专业、科目、题型、正文字段,再通过自定义的一个函数通过正文字段计算出正文哈希字段,如上表所示,随后通过SQL语句:
SELECT DISTINCT 正文, 正文哈希 FROM 临时表 AS A LEFT JOIN 问题正文表 AS B ON A.正文哈希=B.正文哈希 WHERE A.正文=B.正文
去重时却发现DISTINCT去重失效了,如上面的表中,ID为1和3的行正文和正文哈希均完全相同,但却仍然两个都显示出来了,尝试了很久才发现是因为正文哈希字段设置了索引,导致DISTINCT失效,去掉该字段的索引就恢复正常了,但不知道为什么索引会影响DISTINCT去重。
PS:问题原因找到了,确认这是Access的一个BUG,触发条件为 正文字段为备注 (Memo)、使用 LEFT JOIN (子查询)时有时就会出现,解决办法为在出现BUG的语句后再添加一个WHERE子句,例如
SELECT DISTINCT 正文, 正文哈希 FROM 临时表 AS A LEFT JOIN 问题正文表 AS B ON A.正文哈希=B.正文哈希 WHERE A.正文=B.正文 AND (A.正文哈希=0 OR A.正文哈希<>0)
可以HACK掉这个BUG