如何使用mysql2 gem创建预准备语句?

我尝试使用谷歌来回答这个看似简单的问题,但令我惊讶的是,它没有帮助。

我的rails应用程序中的代码目前正在使用mysql gem的’prepare’方法。 切换到mysql2时,会出现错误:

undefined method `prepare' for #<Mysql2::Client::0....... 

所以我尝试寻找’prepare’方法的一个版本,但到目前为止这个搜索都没有成功。 任何人都可以帮我解决这个问题吗?

编辑:如果这是不可能的,有人可以让我知道是否有办法简单地用mysql2库中的东西参数化我的查询?

mysql2 gem现在支持根据文档准备好的语句。

语法如下:

 statement = @client.prepare("SELECT * FROM users WHERE login_count = ?") result1 = statement.execute(1) result2 = statement.execute(2) 

这是在2015年6月添加了合并拉取请求。

UPDATE

正如Ryan Rapp正确指出的那样,mysql2现在支持预处理语句。 从自述文件中提取以下代码段:

 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") 

谢谢瑞恩!

原帖

我也没有找到这样的function; 无论是来源还是文档 。 也许以下代码段可以替代您的需求? (在mysql2 gem的文档中找到):

 escaped = client.escape("gi'thu\"bbe\0r's") results = client.query("SELECT * FROM users WHERE group='#{escaped}'") 

我换掉了使用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)这样的Ruby错误'read_eof_packet': packet is not EOF (Mysql::ProtocolError) ,诀窍就是gem uninstall ruby-mysql而不是gem install ruby-mysql-ext (或者在你的Gemfile中使用gem’ruby gem 'ruby-mysql-ext' ),这将替换Ruby实现,这个实现还不兼容Ruby 2.0(或者至少对我来说不起作用)简单的C绑定。

要明确的是,如果在安装ruby-mysql-extruby-mysql require 'mysql'同时确实require 'mysql' ,它将加载Ruby版本。 可能有一种方法需要在特定的gem中,但我没有时间查找它。

是的,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 !!

我也很惊讶准备方法丢失了。 当然,在一个常见的ActiveRecord和Mysql2设置中,ActiveRecord必须转义字符串,而不是使用libmysql,我觉得有点担心。

在此期间,您可以使用https://github.com/brianmario/mysql2/tree/stmt

据我所知,Rails和MySQL Active Record适配器对预准备语句没有任何支持:

http://patshaughnessy.net/2011/10/22/show-some-love-for-prepared-statements-in-rails-3-1

这是因为它们实际上对加速语句没有任何用处,并且由于MySQL缺乏查询规划,实际上可能会减慢速度。

您也可以使用mysql2-cs-bind gem: https : //github.com/tagomoris/mysql2-cs-bind