Возможно повреждена база данных sqlite? - PullRequest
0 голосов
/ 27 августа 2018

Итак, у меня есть эта база данных SQLite3 . Я заметил проблему, что при попытке выбрать песни, используя столбец uid, он не возвращает никаких строк; например:

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

Даже если строка с указанным идентификатором существует. Замена '=' на 'LIKE' возвращает правильную строку.

Я смог это исправить используя:

UPDATE songs SET uid = uid || ''

Это типичный случай повреждения БД? Или это может быть ошибка sqlite? Как это могло случиться?

1 Ответ

0 голосов
/ 28 августа 2018

Я не верю, что это признак коррупции, скорее, как обрабатывается = .

Например, рассмотрим следующее: -

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 и, таким образом, совпадение.

Проблема (идентификатор хранится как 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

Следовательно, преобразование столбца в тип TEXT явно (CAST) или неявно (некоторые функции, такие как TRIM) решает проблему. Обратите внимание, что SUBSTR возвращает байты из BLOB, поэтому не будет преобразовывать тип столбца и, следовательно, substr(uid,1) не работает.


Примечание

Выполнение вышеуказанного минус условие where указывает, что некоторые строки имеют тип столбца TEXT для столбца uid, согласно: -

enter image description here

...