0

Delphi XE では、文字列の crc32 ハッシュを SQlite データベースの INTEGER として宣言された列に保存しています。私の理解では、SQlite は整数型 (int、int64、signed、unsigned) を区別しません。データベースに関する限り、それらはすべて同じです。しかし、ロングワードとして宣言された値を Delphi に保存すると、後で WHERE 句がその値と一致しなくなります。

私の挿入ステートメント(ここでトリミング)は次のとおりです。

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

ロングワード値は 2 番目のパラメーターにバインドされ、すべてがうまくいきます。しかし、私がするとき

SELECT id FROM main WHERE crc = ?;

クエリは結果を返しません。

SQLiteSpyでデータベースを表示すると、ロングワード値が負の整数として表示されます。その表示からコピーして貼り付けた負の値で上記の SELECT を実行すると、クエリは期待されるレコードを返します。

ロングワード値を INSERT ステートメントにバインドすると、同じロングワード値を SELECT ステートメントにバインドすると、SQLIte は別のことを行うように見えます。値を整数にキャストすると(SQL ではなく Delphi コードで)問題が解決しますが、その必要はなく、他の場所でのキャストを忘れがちです。より良い解決策はありますか?SQLite は正しく動作していますか?

4

1 に答える 1

1

問題は SQLite にあるのではなく、パラメータを SQLite エンジンにバインドする方法にあります。

使用している SQlite フレームワークに応じて、Int64 をステートメントに明示的にバインドする必要があります。

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

たとえば、Cardinal として宣言された 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));

いずれの場合も、パラメーターのバインドに関する独自のコードを表示しないと、コードの何が問題なのかを知ることは困難です。

于 2011-01-21T14:56:16.483 に答える