2010-03-23 20 views
5

Procedura prosty przechowywane w MySQL:Jak wywołać procedurę przechowywaną MySQL z Rails?

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

Rozpoczyna Szyny konsoli:

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

Wygląda dobrze. ALE, więcej połączeń do tej samej procedury przechowywanej za pośrednictwem istniejącego połączenia spowoduje Commands zsynchronizowany błędu:

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

Błąd można usunąć przez „przeładować” polecenie w konsoli:

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

Jak mogę wywołać procedurę przechowywaną MySQL z Rails?

+0

zamieścić jakieś informacje uzupełniające w: http://www.ruby-forum.com/topic/193977#899074 (ze względu na SO nie obsługuje listing kodu w komentarzu) Może” connect! jeśli! active? "może być poprawką.Nie jestem pewien, czy jest to odpowiedź na to pytanie. – ohho

+0

Podsumowanie w moim dzienniku sieci: http://ho.race.hk/blog/?p=231 – ohho

Odpowiedz

4

EDIT:

-

Korzystanie ActiveRecord::Base.connections.exec_query() jest tak daleko, jak mogę powiedzieć DUŻO lepiej podejścia tylko dlatego, że zwraca tablicę skrótów, jak można by się spodziewać, który ActiveRecord::Base.connections.execute nie.

Documentation

-

Proszę przeczytać edytuj powyżej, jestem pozostawiając poniżej.

Chociaż zdaję sobie sprawę, że to pytanie jest dość stare i ponieważ linki opublikowane przeze mnie mają numer 404, to ostatnio miałem ten sam błąd.

udało mi się go naprawić, wykonując następujące czynności:

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

Po usunięciu połączenia, można uruchamiać żadnych innych zapytań, gdzie jak wcześniej byłoby nie powiodła się próbuje uzyskać dostęp do bazy danych przez szyny lub inny zapisany proces.

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

- EDIT:

Warto też wspomnieć, że nie należy przechowywać połączenia ActiveRecord w zmiennej, jak na stanowisku leente w tej link

„nie cache to!

Nie przechowuj połączenia w zmiennej, ponieważ inny wątek może próbować go użyć, gdy jest już sprawdzony z powrotem w puli połączeń. Zobacz: 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) 
Powiązane problemy