【问题标题】:Sqlite WHERE clause and Delphi XE longword valuesSqlite WHERE 子句和 Delphi XE 长字值
【发布时间】:2011-01-21 14:05:05
【问题描述】:

在 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 的行为是否正确?

【问题讨论】:

  • 为什么不使用有符号整数?如果这就是数据库想要的,那么也许你应该使用它。了解数据库是如何存储数据的,而不是猜测和反复试验,这对您是有益的。
  • @David 您可以将无符号的 32 位(即 DWORD=cardinal)存储到 Int64 中而无需任何技巧。问题不在于 SQlite,而在于 moodforaday 在绑定时对 DWORD 值进行类型转换。

标签: delphi sqlite integer delphi-xe mismatch


【解决方案1】:

问题不在于 SQLite,而在于您将参数绑定到 SQLite 引擎的方式。

根据您使用的 SQlite 框架,您必须明确地将 Int64 绑定到您的语句:

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

例如,使用我们的框架,将 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));

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

【讨论】:

  • 谢谢。我使用的是 bind_int,而不是 bind_int64。这似乎足够了,因为 longword 是一个 32 位的值。 (我使用的是 DISQLite,其中 Delphi 类的绑定方法直接映射到 SQlite 的 sqlite3_bind_XX 语句。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
相关资源
最近更新 更多