2

私は md5 チェックサムを sqlite テーブルに保存しようとしていますが、ほとんど常にうまく機能します (何万ものファイルに対して)。しかし、ある特定のファイルについては、事態は奇妙になります。以下の例のチェックサムには、sqlite を混乱させる「魔法の」性質があるように思えます。

SQLite version 3.6.22
Enter ".help" for instructions
sqlite> CREATE TABLE files (md5 STRING UNIQUE NOT NULL);
sqlite> INSERT INTO files (md5) values ("8534112824210843669373e916873875");
sqlite> INSERT INTO files (md5) values ("9534112824210843669373e916873875");
SQL error: column md5 is not unique
sqlite> SELECT * FROM files;
Inf
sqlite>

2 番目の文字列は似ていますが、明らかに異なることに注意してください。他のほぼすべての文字列で試すことができ、問題なく動作します。この動作の理由は何ですか? sqlite でバグを見つけましたか?

解決済み「STRING」列タイプは、何らかの理由で、sqlite では「数値親和性」を持っています。つまり、可能であれば数値として解釈されます。私が望むことを行う正しい方法は、「TEXT」列タイプを使用することです。とにかく答えてくれてありがとう!

4

2 に答える 2

4

列タイプはSTRING、何らかの理由で、SQLiteで「数値アフィニティ」を持ちます。つまり、可能であれば、数値として解釈されます。

チェックサム8534112824210843669373e916873875には単一の値が含まれているため、チェックサムはfloat値に似てeいます(指数表記を使用するとfloatのように見えます)。したがって、結果として、それは数値として解釈されます。

通常のテキスト文字列を格納する正しい方法は、TEXT列タイプを使用することです。

于 2013-01-06T23:38:29.200 に答える
3

私の最善の推測では、二重引用符ではなく単一引用符を使用する必要があります。

INSERT INTO files (md5) values ('8534112824210843669373e916873875');
INSERT INTO files (md5) values ('9534112824210843669373e916873875');

これは文字列の適切な区切り文字です。

ドキュメントによると、何かを二重引用符で囲むと、識別子として扱われます。これらの 2 つの値は、たまたま非常に大きな浮動小数点数のように見えますが、疑似科学的な形式です。6.023e23 は有効な数値です。私の推測では、これらは最大の浮動小数点値または非数値のいずれかに変換されているため、両方が等しいということです。

SQLFiddle で少しテストした後、この動作は文字列の仕組みのようです。検討:

select 1e2  --> 100
select '1e2'  --> 1e2
select cast('1e2' as string)  --> 100
select cast('1e2' as varchar(255))  --> 1e2

テーブルのデータ型を文字列から varchar に変更できますか? これは、string が数値、varchar と親和性があるためです (これによると)

于 2013-01-06T22:18:59.943 に答える