如何从Rails调用MySQL存储过程?

8

MySQL中的简单存储过程:

CREATE PROCEDURE `proc01`()
BEGIN
 SELECT * FROM users;
END

启动Rails控制台:

$ script/console
Loading development environment (Rails 2.3.5)
>> User.connection.execute("CALL proc01")
=> #<Mysql::Result:0x10343efa0>

看起来不错。但是,如果通过现有连接再次调用相同的存储过程,将导致命令不同步错误:

>> 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!”命令来清除:
>> reload!
Reloading...
=> true
>> User.connection.execute("CALL proc01")
=> #<Mysql::Result:0x1033f14d0>
>> 

我该如何从Rails中调用MySQL存储过程?

我在 http://www.ruby-forum.com/topic/193977#899074 上发布了一些后续信息(由于 SO 不支持在评论中列出代码)。也许 "connect! if !active?" 可以解决问题,但我不确定它是否回答了这个问题。 - ohho
我的网志总结:http://ho.race.hk/blog/?p=231 - ohho
1个回答

7

编辑:

--

据我所知,使用ActiveRecord::Base.connections.exec_query()是更好的选择,因为它返回预期的哈希数组,而ActiveRecord::Base.connections.execute则不会。

文档

--

请先阅读上面的编辑内容,下面的内容仅供参考。

虽然我意识到这个问题很老,而且由于ohho发布的链接已经404了,但我最近遇到了同样的错误。

我通过以下方式解决了这个问题:

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在这个链接中所述那样将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) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接