C ++, sqlite3.Как работать с полем BLOB, когда оно используется в качестве условия запроса? - PullRequest
0 голосов
/ 21 февраля 2019

Я получил базу данных sqlit3 и не могу ее изменить.Мне нужно получить запись с кодом «5000154130» и номером «03719552» из таблицы t_major.

Из Navicat я обнаружил, что код и тип номера все VARCHAR . В Navicatзначениями кода и номера являются «5000154130» и «03719552», но после того, как я экспортировал запись, значение изменилось на «NTAwMDE1NDEzMAA =» и «MDM3MTk1NTMA».

Исходная sql вставки - "INSERT INTO "main"."t_major" ("code","number",...) VALUES(X'5000154130',X'03719552',...);".Этот X должен означать BLOB .

Все следующие sql не могут получить результат.

неверный sql

SELECT * FROM t_major WHERE code='5000154130' and number='03719552';
SELECT * FROM t_major WHERE code=hex('5000154130') and hex(number='03719552');
SELECT * FROM t_major WHERE code='5000154130' and number LIKE '03719552';

Только это работает.

SELECT * FROM t_major WHERE code LIKE '%5000154130%' and number LIKE '%03719552%';

Любое предложение?

1 Ответ

0 голосов
/ 21 февраля 2019

https://www.sqlite.org/datatype3.html является необходимым чтением для понимания того, как работает Sqlite.Ваш вопрос говорит о том, что вы его не читали.

Я обнаружил, что все коды и типы номеров VARCHAR

Sqlite не имеет типа VARCHAR;когда он используется в определении столбца, он рассматривается как имеющий сходство TEXT, поскольку в нем есть строка "CHAR".Но вы вставляете BLOB в таблицу.Sqlite не будет преобразовывать большой двоичный объект в любой другой тип при сохранении его в таблице, независимо от сродства столбца.

В первые три SELECT s вы затем сравниваете большой двоичный объект в таблице (X'5000154130') к текстовому значению ('5000154130'), используя =.Это сравнение никогда не будет правдой:

Из документации (выделение добавлено):

Результаты сравнения зависят от классов хранения операндов, согласно следующемуправила:

  • Значение с классом хранения NULL считается меньшим, чем любое другое значение (включая другое значение с классом хранения NULL).

  • AnЗначение INTEGER или REAL меньше любого значения TEXT или BLOB.Когда INTEGER или REAL сравнивается с другим INTEGER или REAL, выполняется числовое сравнение.

  • Значение TEXT меньше значения BLOB .Когда сравниваются два значения TEXT, для определения результата используется соответствующая последовательность упорядочения.

  • При сравнении двух значений BLOB результат определяется с помощью memcmp ().

Ваш четвертый ... тоже не должен совпадать.Это не в моем тестировании.Даже если sqlite обрабатывает BLOB-объект как текст в случае LIKE, сравниваемые значения не совпадают (BLOB-объект X'0102' - это байты 0x01 0x02, строка '0102' - это байты 0x30 0x31 0x30 0x32)


По сути, если вы хотите рассматривать эти значения как строки, не вставляйте их как BLOB-объекты.Если вы не можете это контролировать, ищите записи, сравнивая их с соответствующими каплями, а не со строками.


Редактировать:

Я не знаю, что вы подразумеваете под экспортировал запись , но NTAwMDE1NDEzMAA= - это кодировка Base64 строки '5000154130' (UAAVQTA= - это кодировка Base64 blob X'5000154130').

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...