A simple stored procedure in MySQL:
CREATE PROCEDURE `proc01`()
BEGIN
SELECT * FROM users;
END
Starts Rails console:
$ 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?
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.
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.
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.
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
"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"
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With