Можно ли вызвать хранимую процедуру MySQL из Ruby? - PullRequest
5 голосов
/ 23 января 2009

Когда я пытаюсь вызвать хранимую процедуру из Rails, я получаю следующее исключение:

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

В Rails Wiki есть страница, где обсуждается патч для адаптера MySQL, который решает эту проблему, но он устарел и, похоже, больше не работает.

Код конфигурации правильно разрешает хранимые процедуры, но он все еще имеет проблему с синхронизацией соединения после вызова хранимой процедуры, и новый метод call_sp больше не работает.

Любые предложения о том, как заставить это работать?

Это код, который я использую:

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

Выдает одно и то же исключение независимо от того, возвращает ли * 1016 какие-либо результаты или нет.

Ответы [ 3 ]

2 голосов
/ 06 сентября 2009

Я отправил патч для Rails 2.3.4, который предоставляет опцию конфигурации для решения этой проблемы. Пожалуйста, зайдите на мой билет и покажите свою поддержку для него!

https://rails.lighthouseapp.com/projects/8994/tickets/3151-mysql-adapter-update-to-enable-use-of-stored-procedures

1 голос
/ 23 января 2009

Используете ли вы ActiveRecord :: Base.connection.execute? Этот метод должен позволить вам выполнить произвольный оператор SQL, который наивно не поддерживается в оболочке Active Record.

1 голос
/ 23 января 2009

Будет ли это работать, чтобы обернуть процедуру в функцию? Если в Ruby не выполняется возврат строк (...can't return a result set in the given context...), это можно исправить:

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'

Хотя, на самом деле, это не очень расширяемое решение.

Продолжение: я очень люблю Ruby / ActiveRecord, но этот пример определенно работает

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

Использование CALL tProc() привело к ошибке, аналогичной вашей.

...