2011-01-21 20 views
0

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

私のinsert文は次のとおりです。

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

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

SELECT id FROM main WHERE crc = ?; 

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

SQLiteSpyでデータベースを表示すると、ロングワード値は負の整数として表示されます。そのディスプレイからコピー&ペーストされた負の値で上記のSELECTを実行すると、クエリは予想されるレコードを返します。

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

+0

なぜ符号付き整数を使用しないのですか?それがDBが望んでいるものなら、おそらくあなたはそれでロールすべきです。試行錯誤を推測して使用するのではなく、DBがデータをどのように格納するかを知ることは有益でしょう。 –

+0

@David何もせずにInt64に符号なし32ビット(つまりDWORD =基数)を格納することができます。この問題はSQliteではなく、moodforadayがバインド時にDWORD値を型キャストする方法にあります。 –

答えて

1

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

使用しているSQLiteのフレームワークによって、あなたが明示的にあなたの声明にInt64型をバインドする必要があります。たとえば

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

を、私たちのフレームワークを使用して、CRCが枢機卿として宣言し、これを使用する必要があります。コード(およびNOT任意の整数(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_int64ではなくbind_intを使っていました。ロングワードは32ビットの値なので、十分であるように見えました。 (私は、DelphiクラスのバインドメソッドがSQliteのsqlite3_bind_XXステートメントに直接マップするDISQLiteを使用しています)。 –