Как вызвать хранимую процедуру MySQL из Rails?

5

Простая хранимая процедура в MySQL:

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

Запускает консоль Rails:

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

Выглядит хорошо. НО, вызов вызова одной и той же хранимой процедуры через существующее соединение приведет к ошибке Команды не синхронизируются:

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

Ошибка может быть очищена с помощью "перезагрузки!". команды в консоли:

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

Как я могу вызвать хранимую процедуру MySQL из Rails?

  • 0
    Я публикую некоторую дополнительную информацию по адресу: ruby-forum.com/topic/193977#899074 (из-за того, что SO не поддерживает перечисление кода в комментариях). Возможно, "connect! If! Active?" может быть исправлением. Не уверен, что это ответ на этот вопрос.
  • 0
    Резюме в моем веб-журнале: ho.race.hk/blog/?p=231
Теги:
stored-procedures

1 ответ

4

EDIT:

-

Использование ActiveRecord::Base.connections.exec_query() - это насколько я могу сказать лучше MUCH, потому что он возвращает массив хэшей, как и следовало ожидать, а ActiveRecord::Base.connections.execute - нет.

Документация

-

Пожалуйста, прочитайте приведенное выше изменение, я оставляю ниже для справки.

Пока я понимаю, что этот вопрос довольно старый, и потому что ссылки ohho, опубликованные, имеют 404'd, у меня была такая же ошибка в последнее время.

Мне удалось исправить это, выполнив следующие действия:

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

После того, как вы очистили соединения, вы можете запускать любые другие запросы, которые, как и раньше, потерпели бы неудачу при попытке доступа к базе данных через рельсы или другую сохраненную процедуру.

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

- EDIT:

Также стоит упомянуть, что не следует сохранять соединение ActiveRecord в переменной как в leente post на этой ссылке

"Не кешируйте его!

Не храните соединение в переменной, потому что другой поток может попытаться использовать его, когда он уже проверен обратно в пул соединений. См.: 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) 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню