0

在 Delphi XE 中,我将字符串的 crc32 哈希存储在 SQlite 数据库中,在声明为 INTEGER 的列中。我的理解是 SQlite 不区分整数类型:int、int64、有符号和无符号,就数据库而言,它们都是相同的。但是,当我在 Delphi 中存储声明为 longword 的值时,WHERE 子句稍后无法匹配该值。

我的插入语句(此处删减)是:

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

长字值绑定到第二个参数,一切顺利。但是当我这样做时

SELECT id FROM main WHERE crc = ?;

查询不返回任何结果。

在SQLiteSpy中查看数据库,长字值显示为负整数。如果我使用从该显示复制并粘贴的负值执行上述 SELECT,则查询将返回预期的记录。

似乎当我将长字值绑定到 INSERT 语句时,SQLIte 会在我将相同的长字值绑定到 SELECT 语句时执行其他操作。将值转换为整数(在 Delphi 代码中,而不是在 SQL 中)可以解决问题,但这不是必需的,而且很容易忘记在其他地方进行转换。有更好的解决方案吗?SQLite 的行为是否正确?

4

1 回答 1

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));

在所有情况下,如果不显示您自己的有关绑定参数的代码,就很难知道您的代码有什么问题。

于 2011-01-21T14:56:16.483 回答