2009-01-23 33 views
5

Cuando trato de llamar a un procedimiento almacenado desde rieles, me sale esta excepción:¿Es posible llamar a un procedimiento almacenado de MySQL desde Ruby?

ActiveRecord::StatementInvalid: Mysql::Error: PROCEDURE pipeline-ws_development.match_save_all can't return a result set in the given context: call match_save_all() 
    from /Users/otto/Projects/Futures/src/pipeline-ws/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:150:in `log' 
    from /Users/otto/Projects/Futures/src/pipeline-ws/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:281:in `execute' 
    from (irb):3 

Hay una página en el Rails Wiki that discusses a patch para el adaptador de MySQL que resuelve este problema, pero es fuera de fecha y doesn Parece que ya no funciona.

El código de configuración habilita los procedimientos almacenados correctamente, pero todavía tiene el problema de que la conexión no se sincroniza después de una llamada a un procedimiento almacenado y el nuevo método call_sp ya no funciona.

¿Alguna sugerencia de cómo hacerlo funcionar?

Este es el código que estoy usando:

ActiveRecord::Base.connection("call storedproc()") 

Se lanza la misma excepción si storedproc() retornos ningún resultado o no.

Respuesta

1

¿Funcionaría para envolver el procedimiento en una función? Si barfing de Ruby debido a que no devuelve filas (...can't return a result set in the given context...), esto puede solucionarlo:

 
DELIMITER $ 

CREATE PROCEDURE tProc() 
BEGIN 
    SET @a = 'test'; 
END; 
$ 

CREATE FUNCTION tFunc() 
RETURNS INT 
BEGIN 
    CALL tProc(); 
    RETURN 1; 
END; 
$ 

DELIMITER ; 

SELECT tFunc() FROM DUAL; 
>> 1 

SELECT @a FROM DUAL; 
>> 'test' 

Aunque, siendo realistas, esto no es una solución muy extensible.

Seguimiento: Estoy bastante n00by en Ruby/ActiveRecord, pero este ejemplo definitivamente las obras

 
ActiveRecord::Base.establish_connection(authopts) 

class TestClass < ActiveRecord::Base 
end 

test_class = TestClass.new 
puts %{#{test_class.connection.select_one('SELECT tFunc() AS tf FROM DUAL')}} 
>> tf1 

Usando CALL tProc() dio lugar a un error similar a la suya.

+0

Su ejemplo funciona, pero con nuestro procedimiento almacenado consigo "ERROR 1415 (0A000): No se permite devolver un conjunto de resultados de una función". Voy a hablar con el tipo que los escribió y ver si no podemos reescribirlos para devolver cosas como su ejemplo. – Otto

+1

Esto nos mueve hacia adelante, pero todavía tenemos un par de procesos que necesitan devolver una gran cantidad de datos que no funcionarán en las variables. – Otto

+0

Seguí adelante y acepté, ya que esta parece ser la mejor solución actual. Todavía existe el problema de devolver muchos datos, pero han pasado unos días y nadie ha encontrado algo mejor. No creo que exista sin arreglar el adaptador MySQL. – Otto

1

¿Está utilizando ActiveRecord :: Base.connection.execute? Este método debería permitirle ejecutar alguna declaración SQL arbitraria que no sea soportada ingenuamente en el contenedor Active Record.

+1

Eso es lo que estoy usando, y recibo esa excepción. – Otto

Cuestiones relacionadas