2010-03-23 2 views
5

Простая хранимая процедура в MySQL:Как вызвать хранимую процедуру MySQL из Rails?

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

Запускает Рельсы консоли:

$ 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! 
Reloading... 
=> true 
>> User.connection.execute("CALL proc01") 
=> #<Mysql::Result:0x1033f14d0> 
>> 

Как я могу вызвать хранимую процедуру MySQL из Rails?

+0

я выкладываю некоторые последующую информацию по адресу: http://www.ruby-forum.com/topic/193977#899074 (из-за SO не поддерживает листинга кода в комментарии) Может» подключиться! if! active? "может быть исправлением.Не уверен, что это ответ на этот вопрос. – ohho

+0

Резюме в моем веб-журнале: http://ho.race.hk/blog/?p=231 – ohho

ответ

4

EDIT:

-

Использование ActiveRecord::Base.connections.exec_query() это, насколько я могу сказать НАМНОГО лучше подход только потому, что он возвращает массив хэшей, как можно было бы ожидать, что ActiveRecord::Base.connections.execute не.

Documentation

-

Пожалуйста, прочтите править выше, я оставляю ниже для справки.

Хотя я понимаю, что этот вопрос довольно старый, и поскольку ссылки ohho, опубликованные, имеют 404'd, у меня была такая же ошибка в последнее время.

я был в состоянии исправить это, выполнив следующие действия:

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

После того, как вы очистили соединения, вы можете запускать любые другие вопросы, где, как до того, как провалились бы при попытке получить доступ к базе данных через рельсы или другую сохраненную процедуру.

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

- EDIT:

Стоит также отметить, что не следует хранить соединение ActiveRecord в переменной, как на пост leente на этом link

«Не кэшировать это

Не храните соединение в переменной, потому что другой поток может попытаться использовать его, когда он уже проверен обратно в пул соединений. См.:«

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) 
Смежные вопросы