如何从Rails调用MySQL存储过程?
MySQL中的一个简单存储过程 :
CREATE PROCEDURE `proc01`() BEGIN SELECT * FROM users; END
启动Rails控制台:
$ script/console Loading development environment (Rails 2.3.5) >> User.connection.execute("CALL proc01") => #
看起来不错。 但是,通过现有连接再次调用同一存储过程将导致命令不同步错误:
>> User.connection.execute("CALL proc01") ActiveRecord::StatementInvalid: Mysql::Error: Commands out of sync; you can't run this command now: CALL proc01 from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract_adapter.rb:219:in `log' from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/mysql_adapter.rb:323:in `execute' from (irb):2
可以通过“重新加载”清除错误! 控制台中的命令:
>> reload! Reloading... => true >> User.connection.execute("CALL proc01") => # >>
如何从Rails调用MySQL存储过程?
编辑:
–
使用ActiveRecord::Base.connections.exec_query()
是因为它可以告诉一个更好的方法,因为它返回一个预期的哈希数组,而ActiveRecord::Base.connections.execute
则没有。
文档
–
请阅读上面的编辑,我将离开以下作为参考。
虽然我意识到这个问题已经很老了,因为发布的链接有很多,但我最近也有同样的错误。
我能够通过执行以下操作来修复它:
result = ActiveRecord::Base.connection.execute("call example_proc()") ActiveRecord::Base.clear_active_connections!
一旦清除了连接,就可以运行任何其他查询,就像之前尝试通过rails或其他存储过程访问数据库一样失败。
http://apidock.com/rails/v3.2.13/ActiveRecord/Base/clear_active_connections%21/class
– 编辑:
还值得一提的是,根据leente在此链接上的post,不应将ActiveRecord连接存储在变量中
“不要缓存它!
不要在变量中存储连接,因为当另一个线程已经重新检入连接池时,可能会尝试使用它。 请参阅: ConnectionPool “
connection = ActiveRecord::Base.connection #WRONG threads = (1..100).map do Thread.new do begin 10.times do connection.execute("SELECT SLEEP(1)") # WRONG ActiveRecord::Base.connection.execute("SELECT SLEEP(1)") # CORRECT end puts "success" rescue => e puts e.message end end end threads.each(&:join)