可能损坏的sqlite数据库?

时间:2018-08-27 20:16:05

标签: sqlite corruption corrupt data-corruption

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

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

即使存在具有给定uid的行。用'LIKE'代替'='返回正确的行。

我可以使用以下方式修复它:

UPDATE songs SET uid = uid || ''

这是数据库损坏的典型情况吗?还是可能是一个sqlite bug?这怎么可能发生?

1 个答案:

答案 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)选择适当的行。结果输出为:-

enter image description here

  • 注意到'yzoiaVuicn5ISq1+4DaKGbM3trht/z/ONNm+vA==' = uid AS reversematch返回false,但所有其他比较返回1,即true,因此匹配。

问题(uid存储为BLOB)

问题是 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=='

结果:-

enter image description here

因此可以将列显式(CAST)或隐式转换为TEXT类型(某些功能,例如TRIM)可以解决此问题。请注意,SUBSTR从BLOB返回字节,因此不会转换列类型,因此substr(uid,1)不起作用。


注意

运行上述内容少了where子句,表明某些行的uid列具有TEXT的列类型,如:-

enter image description here