首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sqlite3可变字符与"like“匹配,但不与"=”匹配

sqlite3可变字符与"like“匹配,但不与"=”匹配
EN

Stack Overflow用户
提问于 2011-09-16 06:02:43
回答 2查看 571关注 0票数 2

使用Rails3.1和sqlite3进行开发和测试环境。

在迁移中添加了新表:

代码语言:javascript
运行
复制
create_table :api_keys do |t|
  t.string :api_key
  t.integer :user_id
  t.timestamps
end

这将生成一个具有以下模式的表:

代码语言:javascript
运行
复制
create_table "api_keys", :force => true do |t|
  t.string   "api_key"
  t.integer  "user_id"
  t.datetime "created_at"
  t.datetime "updated_at"
end

在ActiveRecord模型中:

代码语言:javascript
运行
复制
before_create :fill_api_key

private

def fill_api_key
  self.api_key = SecureRandom.hex(30)
end

ActiveRecord的动态查找器方法find_by_api_key(api_key)不起作用(返回nil)。同上:

代码语言:javascript
运行
复制
ApiKey.where({:api_key => 'something'}).first

在sqlite3中,我执行以下操作:

代码语言:javascript
运行
复制
insert into api_keys (id, api_key) values (-1, '12345');

如果我现在运行select:

代码语言:javascript
运行
复制
select api_keys.* from api_keys where api_keys.api_key = '12345';

将会找到该记录。

如果我运行未过滤的select命令,则会显示从我的应用程序创建的预先存在的数据:

代码语言:javascript
运行
复制
select api_keys.* from api_keys;

如果我试图通过在查询中粘贴一个来自这些预先存在的记录之一的长十六进制字符串来查找预先存在的记录:

代码语言:javascript
运行
复制
select api_keys.* from api_keys where api_keys.api_key = 'long hex string';

则不返回任何结果。如果我尝试这样做:

代码语言:javascript
运行
复制
select api_keys.* from api_keys where api_keys.api_key like 'long hex string';

然后我就会得到一个匹配。

我已经在api_keys.api_key上创建了一个索引,但没有任何效果。

这个问题影响了我的应用程序中的另一个模型,该模型使用Digest::SHA1::hexdigest生成类似的随机十六进制数字字符串。

詹姆斯

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-19 08:28:10

好了,我想我已经弄明白了。问题不在于这是Rails 3.1,而是你可能已经从Ruby 1.8.7迁移到了Ruby 1.9.2。

在Ruby1.9中,所有的字符串现在都是编码的。默认情况下,所有字符串都应为UTF-8,但是,SecureRandom.hex(30)将返回ASCII-8BIT编码。

您可以使用以下命令在sqlite3中确认这一点:.dump api_keys,您可能会看到api_key字段如下所示:

代码语言:javascript
运行
复制
INSERT INTO "api_keys" VALUES(1,X'376433356530[...]',1);    
INSERT INTO "api_keys" VALUES(1,'1234567890[...]',1);

第一个是由SecureRandom生成的api_key。第二个是通过在控制台中键入来创建的。X表示字段编码为blob,而不是字符串。

要解决此问题,请将您的fill_api_key更改为:

代码语言:javascript
运行
复制
self.api_key = SecureRandom.hex(30).force_encoding('UTF-8')

我刚刚通过这个得到了bit big time,所以希望它能帮助你。

这里有一些关于1.9中对字符串的更改的好细节:http://blog.grayproductions.net/articles/ruby_19s_string

票数 8
EN

Stack Overflow用户

发布于 2011-09-16 06:09:00

如果您使用十六进制数字字符串,如果您想要使用where x=y select,大小写匹配是很重要的。与某些数据库不同,SQLite区分大小写。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7437944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档