如何在 SQLite3 和 Rails 3.1 中打开 REGEXP?
Posted
技术标签:
【中文标题】如何在 SQLite3 和 Rails 3.1 中打开 REGEXP?【英文标题】:How to turn on REGEXP in SQLite3 and Rails 3.1? 【发布时间】:2011-10-13 22:19:08 【问题描述】:我在使用 SQLite3 数据库的 Rails 3 中有以下语句:
word = 'Hello'
word_entry = Word.where("name REGEXP :word", :word => "[[:<:]]#word[[:>:]]")
但是,在 SQLite3 下运行它时,我不断得到:
SQLite3::SQLException: 没有这样的函数:REGEXP
我在 SQLite3 文档中读到它确实支持 REGEXP 函数。 在我的 gemfile 中,我有一行
gem 'sqlite3'
我的数据库配置文件如下所示:
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
有什么想法吗?
解决方案: 我最终找到了this solution。不幸的是,它不适用于 Rails 3。 所以为了使用正则表达式,我最终改用 mysql 而不是 SQLite3。
【问题讨论】:
【参考方案1】:我遇到了同样的问题。我采用了解决方案中使用的代码,将其移植到 Rails 3+ 中,并制作了一个 gem,以便于使用。我希望这会有所帮助。
https://github.com/sei-mi/sqlite3_ar_regexp
【讨论】:
为此,您将获得布朗尼积分(并且您的答案被标记为正确的)。谢谢谢谢谢谢!【参考方案2】:来自fine manual:
REGEXP 运算符是 regexp() 用户函数的特殊语法。默认情况下没有定义 regexp() 用户函数,因此使用 REGEXP 运算符通常会导致错误消息。如果在运行时添加了名为“regexp”的应用程序定义的 SQL 函数,则会调用该函数以实现 REGEXP 运算符。
所以语法支持 REGEXP 但默认的 SQLite 库没有提供它的实现。如果你想要或需要这样的东西,你必须通过一些 C 争论来连接你自己的实现。
大概的理由是 SQLite 的人们希望 SQLite 尽可能小而紧凑,但包含一个完整的正则表达式库会增加大多数人不想要的重量。此外,他们必须选择一个正则表达式库并将其包含在 SQLite 源代码中,否则他们将不得不忍受每个人在 libc 中的正则表达式支持的变幻莫测。我不是 SQLite 开发人员之一,所以这纯粹是猜测。
我猜你可能不得不使用LIKE and GLOB。使用 LIKE 将提供更便携的解决方案。
【讨论】:
不够具体,无法解决我的问题,但这是我问题的正确答案。请参阅我题为RESOLUTION
的问题中的编辑。
@yuval:这是一个很好的发现,可惜它不再起作用了。【参考方案3】:
您可能会在 sqlite3-pcre
包中进行测试,该包为 SQLite 实现了 REGEXP
。
有关类似问题,请参阅 this comment。
【讨论】:
【参考方案4】:我有一个类似的问题,并找到了一个名为 wherex 的 Gem,它有据可查并且开箱即用。
你在上面的表情
Word.where("name REGEXP :word", :word => "[[:<:]]#word[[:>:]]")
会有
Word.where(:name => Regexp.new("[[:<:]]#word[[:>:]]"))
对我来说就像一个魅力:-)
【讨论】:
【参考方案5】:从 sqlite3_ar_regexp 项目的源代码中,我提取了这个:
db = SQLite3::Database.open( database_name )
db.create_function('regexp', 2) do |func, pattern, expression|
func.result = expression.to_s.match(
Regexp.new(pattern.to_s, Regexp::IGNORECASE)) ? 1 : 0
end
【讨论】:
【参考方案6】:从 sqlite3_ar_regexp 项目的源代码中,我提取了这个:
db = ActiveRecord::Base.connection.raw_connection
db.create_function('regexp', 2) do |func, pattern, expression|
func.result = expression.to_s.match(
Regexp.new(pattern.to_s, Regexp::IGNORECASE)) ? 1 : 0
end
改进了ActiveRecord::Base.connection.raw_connection
的先前答案,因此不需要数据库名称
【讨论】:
以上是关于如何在 SQLite3 和 Rails 3.1 中打开 REGEXP?的主要内容,如果未能解决你的问题,请参考以下文章
这个 Rails 文件存储在哪里? db/development.sqlite3
如何在 Rails 3.1 应用程序中完全禁用 CoffeeScript?
如何开始使用 Backbone.js 和 Rails 3.1