可能损坏了 sqlite 数据库?

Possibly corrupt sqlite database?

所以我有 this SQLite3 database。我注意到一个问题,当尝试使用 uid 列 select 歌曲时,它不会 return 任何行;例如:

SELECT * FROM songs WHERE uid = 'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA=='

即使存在具有给定 uid 的行。将“=”替换为 'LIKE' return 正确的行。

我已经能够使用以下方法修复它:

UPDATE songs SET uid = uid || ''

这是数据库损坏的典型案例吗?或者它可能是一个 sqlite 错误?怎么会这样?

我认为这不是腐败的迹象,而是 = 的处理方式。

例如考虑以下内容:-

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 return 是错误的,但所有其他比较 return 1 即是正确的,因此匹配。

问题(uid 存储为 BLOB)

问题是 uid 列的存储 class 为 BLOB,因此类型亲和性为 BLOB。这可以通过使用 typeof 函数添加提取 column/row 类型的列来看出,例如:-

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) 或隐式(某些函数,例如 TRIM)转换为 TEXT 类型可以解决问题。请注意,来自 BLOB 的 SUBSTR return 字节不会转换列类型,因此 substr(uid,1) 不起作用。


备注

运行 以上减去 where 子句表示某些行的 uid 列的列类型为 TEXT,如 :-