在Delphi XE中,我将字符串的crc32哈希存储在SQlite数据库中,在声明为INTEGER的列中。我的理解是SQlite不区分整数类型:int,int64,signed和unsigned,就数据库而言它们都是相同的。但是,当我在Delphi中存储声明为longword的值时,WHERE子句以后无法匹配该值。
我的插入语句(在此处修剪)是:
INSERT INTO main VALUES (id, crc) (?, ?);
长字值绑定到第二个参数,一切顺利。但是当我做的时候
SELECT id FROM main WHERE crc = ?;
查询不返回任何结果。
在SQLiteSpy中查看数据库,长字值显示为负整数。如果我执行上面的SELECT并从该显示中复制并粘贴了负值,则查询将返回预期的记录。
当我将一个长字值绑定到INSERT语句时,似乎当我将相同的长字值绑定到SELECT语句时,SQLIte会执行其他操作。将值转换为整数(在Delphi代码中,而不是在SQL中)可以解决问题,但这不是必需的,并且很容易忘记在其他地方进行转换。有更好的解决方案吗? SQLite的行为是否正确?
答案 0 :(得分:1)
问题不在SQLite中,而在于您将参数绑定到SQLite引擎的方式。
根据您使用的SQlite框架,您必须明确地将Int64绑定到您的语句:
INSERT INTO main VALUES (id, crc) (?, ?);
例如,使用我们的框架,将CRC声明为Cardinal,您必须使用此代码(而不是任何整数(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));
在所有情况下,如果没有显示自己的绑定参数代码,很难知道代码中的错误。