简体   繁体   English

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

[英]How to call MySQL stored procedure from Rails?

A simple stored procedure in MySQL: MySQL中的一个简单存储过程

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

Starts Rails console: 启动Rails控制台:

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

Looks good. 看起来不错。 BUT, any more call to the same stored procedure via the existing connection will result in an Commands out of sync error: 但是,通过现有连接再次调用同一存储过程将导致命令不同步错误:

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

The error can be cleared by a "reload!" 可以通过“重新加载”清除错误! command in the console: 控制台中的命令:

>> reload!
Reloading...
=> true
>> User.connection.execute("CALL proc01")
=> #<Mysql::Result:0x1033f14d0>
>> 

How can I call MySQL stored procedure from Rails? 如何从Rails调用MySQL存储过程?

EDIT: 编辑:

-- -

Using ActiveRecord::Base.connections.exec_query() is as far as I can tell a MUCH better approach just because it returns an array of hashes as one would expect, which ActiveRecord::Base.connections.execute does not. 使用ActiveRecord::Base.connections.exec_query()是据我可以告诉一个更好的办法,只是因为它返回哈希正如人们所预料的数组,其中ActiveRecord::Base.connections.execute没有。

Documentation 文档

-- -

Please read the edit above, I'm leaving the below for reference. 请阅读上面的编辑,我将离开以下作为参考。

While I realise this question is quite old and because the links ohho posted have 404'd, I had this same error recently. 虽然我意识到这个问题已经很老了,并且发布的链接ohho有404'd,但我最近也遇到了同样的错误。

I was able to fix it by doing the following: 我能够通过执行以下操作来修复它:

result = ActiveRecord::Base.connection.execute("call example_proc()") ActiveRecord::Base.clear_active_connections!

Once you've cleared connections, you can run any other queries where as before it would have failed on trying to access the database through rails or another stored proc. 一旦清除了连接,就可以运行任何其他查询,就像之前尝试通过rails或其他存储过程访问数据库一样失败。

http://apidock.com/rails/v3.2.13/ActiveRecord/Base/clear_active_connections%21/class http://apidock.com/rails/v3.2.13/ActiveRecord/Base/clear_active_connections%21/class

-- EDIT: - 编辑:

It's also worth mentioning that one shouldn't store the ActiveRecord connection in a variable as per leente's post on this link 还值得一提的是,根据leente在此链接上的帖子,不应将ActiveRecord连接存储在变量中

"Don't cache it! “不要缓存它!

Don't store a connection in a variable, because another thread might try to use it when it's already checked back in into the connection pool. 不要在变量中存储连接,因为当另一个线程已经重新连接到连接池时,它可能会尝试使用它。 See: ConnectionPool " 请参阅: 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) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM