我使用SQLite3并有一个名为blobs的表,用于存储内容和* hash_value *。
这是架构:
CREATE TABLE "blobs" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"content" blob,
"hash_value" text,
"created_at" datetime NOT NULL,
"updated_at" datetime NOT NULL
);
现在我插入了一些数据。看起来像这样:
1|--- foo
...
|34dc86f45b3dc92b352fd45f525192c0|2012-04-09 17:02:54.219504|2012-04-09 17:02:54.219504
我尝试了以下两个问题:
select * from blobs where hash_value = '34dc86f45b3dc92b352fd45f525192c0';
select * from blobs where hash_value LIKE '34dc86f45b3dc92b352fd45f525192c0';
第一个不起作用,但第二个起作用。我不明白为什么=
运算符不起作用。
我试图将其分解为一个简单的示例,其中我的哈希只是'abc'
并且=有效。我的意思是这个字符串不会太长。
好的,我实际上把它缩小到了这个:
Digest::MD5.hexdigest("foobar")
'3858f62230ac3c915f300c664312c63f'
b = Blob.new(...);b.save!;Blob.find_by_hash(b.hash)
Blob.find(:all, :conditions => ["hash_value = ?", hash_value])
'3858f62230ac3c915f300c664312c63f'
(硬编码字符串),则可以正常工作。但如果生成此字符串,则会出现以下错误:
Failure/Error: Blob.find_by_hash(b.hash_value)[0].load.should == txt
ArgumentError: wrong number of arguments (0 for 1)
我无法像上面所述查询SQLite3。
解决方案
解决方案是:
我不知道为什么sqlite3存在hexdigest的问题,但最终确实存在一些问题。
答案 0 :(得分:2)
两者之间的差异是编码:
Digest::MD5.hexdigest("foobar").encoding #=> #<Encoding:ASCII-8BIT>
Digest::MD5.base64digest("foobar").encoding #=> #<Encoding:US-ASCII>
我认为hexdigest有一个特殊的原因,就是为什么hexdigest有8位编码(这实际上意味着'这是原始数据',但这正是ruby似乎所做的。当ruby sqlite3驱动程序看到ascii-8bit编码时它将值作为blob而不是文本绑定到查询。这反过来会影响sqlite3进行比较的方式(虽然我不明白如何)。
答案 1 :(得分:0)
解决方案是:
使用Digest :: MD5.base64digest(“foobar”)而不是使用Digest :: MD5.hexdigest(“foobar”)。 我不知道为什么sqlite3有hexdigest的问题,但确实有一些可疑的事情。