2010-03-23 36 views
5

Un procedimiento sencillo almacenado en MySQL:¿Cómo llamar al procedimiento almacenado de MySQL desde Rails?

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

Inicia Rails consola:

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

se ve bien. Pero, más llamada al mismo procedimiento almacenado a través de la conexión existente resultará en un comandos de error de sincronización:

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

El error puede eliminarse por un "recargar!" comando en la consola:

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

¿Cómo puedo llamar al procedimiento almacenado de MySQL desde Rails?

+0

puedo enviar alguna información de seguimiento en: http://www.ruby-forum.com/topic/193977#899074 (debido a SO no soporta listado de código en el comentario) Tal vez" conectar! if! active? "puede ser una solución.No estoy seguro de si es la respuesta a esta pregunta. – ohho

+0

Resumen en mi registro web: http://ho.race.hk/blog/?p=231 – ohho

Respuesta

4

EDIT:

-

usando ActiveRecord::Base.connections.exec_query() es por lo que yo puedo decir un enfoque mucho mejor sólo porque devuelve un array de hashes, como cabría esperar, que ActiveRecord::Base.connections.execute no.

Documentation

-

Por favor, lea el texto de arriba, estoy dejando la continuación como referencia.

Aunque me doy cuenta de que esta pregunta es bastante antigua y debido a que los enlaces que publicó ohho tienen 404'd, tuve este mismo error recientemente.

pude solucionarlo haciendo lo siguiente:

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

Una vez que haya limpiado las conexiones, puede ejecutar cualquier tipo de duda donde como antes de que hubiera fallado en tratar de acceder a la base de datos a través de raíles u otro proceso almacenado.

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

- EDIT:

También vale la pena mencionar que no se debe almacenar la conexión ActiveRecord en una variable de acuerdo con el post de leente en este link

"de no caché

No guarde una conexión en una variable, porque otra cadena podría intentar usarla cuando ya se haya registrado en el grupo de conexiones. Ver: 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) 
Cuestiones relacionadas