Когда я пытаюсь вызвать хранимую процедуру из 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()")
Это вызывает то же исключение, независимо от того, возвращает ли storedproc()
какие-либо результаты или нет.
Сработает ли обернуть процедуру функцией? Если 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()
привело к ошибке, аналогичной вашей.
Это продвигает нас вперед, но у нас все еще есть пара процедур, которые должны возвращать много данных, которые не будут работать с переменными.
Я пошел дальше и согласился, так как это, кажется, лучшее текущее решение. По-прежнему существует проблема с возвратом большого количества данных, но прошло несколько дней, и никто не придумал ничего лучшего. Я не думаю, что он существует без исправления адаптера MySQL.
Мне немного непонятно - могут ли проки данные возвращать? Я почти уверен, что процессы в MySQL ничего не возвращают. Вы можете уточнить?
Вы используете ActiveRecord :: Base.connection.execute? Этот метод должен позволить вам выполнить произвольный оператор SQL, который наивно не поддерживается в оболочке Active Record.
Это то, что я использую, и у меня есть это исключение.
Я отправил патч для Rails 2.3.4, который дает возможность конфигурации для решения этой проблемы. Пожалуйста, остановитесь у моего билета и покажите, что вы его поддерживаете!
Ваш пример работает, но с нашей сохраненной процедурой я получаю «ОШИБКА 1415 (0A000): не разрешено возвращать набор результатов из функции». Я собираюсь поговорить с парнем, который их написал, и посмотреть, не сможем ли мы их переписать, чтобы получить такие вещи, как ваш пример.