我尝试使用谷歌来回答这个看似简单的问题,但令我惊讶的是,它没有帮助。
我的rails应用程序中的代码目前正在使用mysql gem的'prepare'方法。切换到mysql2时,会出现错误:
undefined method `prepare' for #<Mysql2::Client::0.......
所以我尝试寻找'prepare'方法的一个版本,但到目前为止这个搜索都没有成功。任何人都可以帮我解决这个问题吗?
编辑:如果这是不可能的,有人可以让我知道是否有办法简单地用mysql2库中的东西参数化我的查询?
答案 0 :(得分:14)
<强>更新强>
正如Ryan Rapp指出的那样,mysql2现在支持预处理语句。以下代码段摘自readme:
statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
result1 = statement.execute(1)
result2 = statement.execute(2)
statement = @client.prepare("SELECT * FROM users WHERE last_login >= ? AND location LIKE ?")
result = statement.execute(1, "CA")
谢谢Ryan!
原帖
我也没有找到这样的功能;既不在source也不在documentation。 也许下面的代码片段可以替代您的需求? (在mysql2 gem的文档中找到):
escaped = client.escape("gi'thu\"bbe\0r's")
results = client.query("SELECT * FROM users WHERE group='#{escaped}'")
答案 1 :(得分:6)
mysql2
gem现在支持根据documentation准备好的语句。
语法如下:
statement = @client.prepare("SELECT * FROM users WHERE login_count = ?")
result1 = statement.execute(1)
result2 = statement.execute(2)
这是added,2015年6月合并拉取请求。
答案 2 :(得分:3)
我换出使用https://github.com/tmtm/ruby-mysql而不是mysql2。令我惊讶的是,对于使用mysql2 gem的人来说,这不是一个更大的交易破坏者。我想那些深入研究SQL的人已经交换到Postgresql了?
如果其他人遇到问题gem install ruby-mysql
后跟require "mysql"
,您会收到像'read_eof_packet': packet is not EOF (Mysql::ProtocolError)
这样的红宝石错误,诀窍是gem uninstall ruby-mysql
而不是gem install ruby-mysql-ext
(或在你的Gemfile中使用gem 'ruby-mysql-ext'
,它将换掉Ruby实现,这个实现还不兼容Ruby 2.0(或者至少对我来说不起作用),用于简单的C绑定。
要明确的是,如果在安装require 'mysql'
和ruby-mysql-ext
的同时执行ruby-mysql
,它将加载Ruby版本。可能有一种方法需要在特定的宝石中,但我没有时间查找它。
答案 3 :(得分:1)
是的,mysql2适配器不支持绑定,直到当前的Rails 4.0。我很惊讶!您可以通过〜/ .rvm / gems / ruby-2.1.1 / gems / activerecord-4.1.1 / lib / active_record / connection_adapters / mysql2_adapter.rb中的代码片段来判断这一点
def exec_query(sql, name = 'SQL', binds = [])
result = execute(sql, name)
ActiveRecord::Result.new(result.fields, result.to_a)
end
alias exec_without_stmt exec_query
# Returns an ActiveRecord::Result instance.
def select(sql, name = nil, binds = [])
exec_query(sql, name)
end
这也有助于您理解:
(在〜/ .rvm / gems / ruby-2.1.1 / gems / activerecord-4.1.1 / lib / active_record / connection_adapters / abstract / database_statements.rb)
# Returns an ActiveRecord::Result instance.
def select_all(arel, name = nil, binds = [])
if arel.is_a?(Relation)
relation = arel
arel = relation.arel
if !binds || binds.empty?
binds = relation.bind_values
end
end
select(to_sql(arel, binds), name, binds)
end
那就是它!我猜我可能会转向Postgres !!
答案 4 :(得分:0)
我还惊讶于缺少准备方法。当然,在一个常见的ActiveRecord和Mysql2设置中,ActiveRecord必须转义字符串,而不是使用libmysql,我觉得有点担心。
答案 5 :(得分:0)
据我所知,Rails和MySQL Active Record适配器对预准备语句没有任何支持:
http://patshaughnessy.net/2011/10/22/show-some-love-for-prepared-statements-in-rails-3-1
这是因为它们实际上对加速语句没有任何用处,并且由于MySQL缺乏查询规划,实际上可能会减慢速度。
答案 6 :(得分:0)
您也可以使用mysql2-cs-bind gem: https://github.com/tagomoris/mysql2-cs-bind