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>

请注意,第二个字符串相似,但明显不同。您可以尝试使用几乎任何其他字符串,它工作正常。这种行为的原因是什么?我在 sqlite 中发现了一个错误吗?

已解决无论出于何种原因,“STRING”列类型在 sqlite 中具有“数字亲和性”,这意味着如果可能,它将被解释为数字。做我想做的事情的正确方法是使用“TEXT”列类型。无论如何,感谢您的回答!

4

2 回答 2

4

无论出于何种原因,列STRING类型在 SQLite 中具有“数字亲和性”,这意味着如果可能,它将被解释为数字。

校验和8534112824210843669373e916873875类似于一个浮点值,因为它恰好包含一个e(使用指数表示法使它看起来像一个浮点数)。因此,它确实被解释为一个数字。

存储普通文本字符串的正确方法是使用TEXT列类型。

于 2013-01-06T23:38:29.200 回答
3

我最好的猜测是你应该使用单引号而不是双引号:

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

这是字符串的正确分隔符。

根据文档,当您将某些内容放在双引号中时,它将被视为标识符。这两个值恰好看起来像非常大的浮点数,采用伪科学格式——你知道,6.023e23 是一个有效数字。我的猜测是这些被转换为最大的浮点值或非数字,所以两者都是相等的。

在对 SQLFiddle 进行了一些测试之后,这种行为似乎是字符串的工作方式。考虑:

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

你能把表中的数据类型从字符串改成varchar吗?这是因为 string 对 numeric 和 varchar 具有亲和力(根据this)。

于 2013-01-06T22:18:59.943 回答