如何从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)