procedimientos - ¿Es posible llamar a un procedimiento almacenado de MySQL desde Ruby?
procedimientos almacenados mysql 2018 (3)
¿Estás 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.
Cuando trato de llamar a un procedimiento almacenado desde Rails, obtengo esta excepción:
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 Rails Wiki que analiza un parche para el adaptador MySQL que resuelve este problema, pero está desactualizado y 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 hacer que esto funcione?
Este es el código que estoy usando:
ActiveRecord::Base.connection("call storedproc()")
Lanza la misma excepción si storedproc()
devuelve cualquier resultado o no.
¿Funcionaría para envolver el procedimiento en una función? Si el rechazo de Ruby debido a que no se devolvieron las 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, de manera realista, esta no es una solución muy extensible.
Seguimiento: estoy bastante n00by en Ruby / ActiveRecord, pero este ejemplo definitivamente funciona
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
El uso de CALL tProc()
produjo un error similar al tuyo.
He enviado un parche a Rails 2.3.4 que ofrece una opción de configuración para solucionar este problema. ¡Pasa por mi boleto y muestra tu apoyo!