所以我有this SQLite3 database。我注意到一个问题,当尝试使用uid列选择歌曲时,它不返回任何行。例如:
SELECT * FROM songs WHERE uid = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA=='
即使存在具有给定uid的行。用'LIKE'代替'='返回正确的行。
我可以使用以下方式修复它:
UPDATE songs SET uid = uid || ''
这是数据库损坏的典型情况吗?还是可能是一个sqlite bug?这怎么可能发生?
答案 0 :(得分:1)
我不认为这是腐败的迹象,而是 = 的处理方式。
例如,考虑以下内容:-
SELECT uid,
TRIM(uid) = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' AS trim1match,
TRIM(uid) = TRIM('yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==') AS trimbothmatch,
CAST(uid AS TEXT) = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' AS casttotextmatch,
'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' LIKE(uid) AS likematch,
'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' = uid AS reversematch
FROM songs
WHERE trim(uid) = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA=='
WHERE
子句使用TRIM(uid)选择适当的行。结果输出为:-
'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' = uid AS reversematch
返回false,但所有其他比较返回1,即true,因此匹配。问题是 uid 列的存储类为 BLOB ,因此类型相似性为 BLOB 。这可以通过添加使用 typeof 函数提取列/行类型的列来看到,例如:-
SELECT uid, typeof(uid),
trim(uid) = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' AS trim1match,
trim(uid) = trim('yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==') AS trimbothmatch,
CAST(uid AS TEXT) = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' AS casttotextmatch,
'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' LIKE(uid) AS likematch,
'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' = uid AS reversematch
FROM songs
WHERE trim(uid) = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA=='
结果:-
因此可以将列显式(CAST)或隐式转换为TEXT类型(某些功能,例如TRIM)可以解决此问题。请注意,SUBSTR从BLOB返回字节,因此不会转换列类型,因此substr(uid,1)
不起作用。
注意
运行上述内容少了where子句,表明某些行的uid列具有TEXT的列类型,如:-