如何使用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-ext
和ruby-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