2011-01-21 3 views
0

В Delphi XE я храню хеш crc32 строки в базе данных SQlite в столбце, объявленном как INTEGER. Я понимаю, что SQlite не различает целые типы: int, int64, signed и unsigned, они все равно, что касается базы данных. Тем не менее, когда я храню значение, объявленное как longword в Delphi, предложение WHERE не может совпадать с этим значением позже.Предложение Sqlite WHERE и значения longword Delphi XE

Моя вставка заявление (урезано здесь) является:

INSERT INTO main VALUES (id, crc) (?, ?); 

Значения длинного слова получает связанное со вторым параметром, и все идет хорошо. Но когда я сделаю

SELECT id FROM main WHERE crc = ?; 

запрос не дал результатов.

Просмотр базы данных в SQLiteSpy, значения longword отображаются как отрицательные целые числа. Если я выполнил вышеуказанный SELECT с отрицательным значением, скопированным и вставленным с этого экрана, запрос вернет ожидаемую запись.

Казалось бы, когда я привязываю значение longword к инструкции INSERT, SQLIte делает что-то еще тогда, когда я связываю одно и то же значение longword с оператором SELECT. Приведение значения в целое число (в коде Delphi, а не в SQL) устраняет проблему, но это не обязательно, и будет легко забыть бросать в других местах. Есть ли лучшее решение? Правильно ли работает SQLite?

+0

Почему вы не используете знаковое целое число? Если это то, чего хочет БД, возможно, вам стоит с ним поработать. Было бы полезно узнать, как БД хранит данные, а не гадает и использует проб и ошибок. –

+0

@ David вы можете хранить 32-значный 32-разрядный (т. Е. DWORD = кардинал) в Int64 без каких-либо трюков. Проблема не в SQlite, а в том, как moodforaday приписывает значение DWORD при привязке. –

ответ

1

Проблема не в SQLite, а в том, как вы привязываете свои параметры к движку SQLite.

В зависимости от структуры SQlite вы используете, вы должны явно связаны в Int64 к выписке:

INSERT INTO main VALUES (id, crc) (?, ?); 

Например, используя нашу базу, с КПР объявлен как кардинал, вы должны использовать этот код (и нЕ любое целое число (CRC)):

sqlite3_check(RequestDB,sqlite3_bind_Int64(Request,2,Int64(CRC))); 

Если приведенный выше код не работает, это всегда будет работать:

var CRC64: Int64; 
    CRC64Rec: TInt64Rec absolute CRC64; 
begin 
    CRC64Rec.Lo := CRC; 
    CRC64Rec.Hi := 0; 
    sqlite3_check(RequestDB,sqlite3_bind_Int64(Request,2,CRC64)); 

Во всех случаях, не показывая свой собственный код о параметрах привязки, трудно понять, что не так в коде.

+0

Спасибо. Я использовал bind_int, а не bind_int64. Это казалось достаточным, так как longword - это 32-битное значение. (Я использую DISQLite, где методы привязки класса Delphi сопоставляются непосредственно с операциями sqlite3_bind_XX SQlite.) –