2016-11-24 11 views
0

По соображениям производительности мне нужно выдавать операторы SQL (вставки и обновления) непосредственно в базу данных. У меня нет никаких проблем с выполнением большого оператора вставки, как:В Ruby on Rails, как я могу отправить несколько операторов обновления в базу данных с помощью dbult db connection object?

@conn = ActiveRecord::Base.connection 
inserts = "INSERT INTO clients (code, name) VALUES ('abc123', 'Alyx'), ('xyz123', 'Gordon') ...many more...\;" 
@conn.execute inserts 

Однако я с трудом исполняющей партии обновлений, как:

updates = "UPDATE clients SET name='Julia' WHERE id=1; UPDATE clients SET name='Eli' WHERE id=2; ...many more..." 
@conn.execute updates 
# or 
@conn.update updates 

, потому что это дает мне ошибку синтаксиса общего SQL:

ActiveRecord::StatementInvalid: Mysql2::Error: You have an error in your SQL syntax; 

Я попытался изменить файл конфигурации database.yml включить флаг MULTI_STATEMENTS без успеха:

flags: 
- MULTI_STATEMENTS 

Единственный способ, которым я сумел сделать эту работу является получение экземпляра клиента mysql2, с установленным флагом:

client = Mysql2::Client.new(host: 'localhost', ... , flags: Mysql2::Client::MULTI_STATEMENTS) 
client.query updates 

, но это не кажется хорошей идеей, поскольку она будет блокировать приложение вместе с драгоценным камнем mysql2.

Это проблема с камнем mysql2, ActiveRecord, или я пропустил что-то важное?

+0

Вы видели это сообщение? http://stackoverflow.com/a/24226826/3366016 Кажется, адаптер mysql2 не может обрабатывать несколько операторов без установки флага, как у вас. PostgreSQL, похоже, справляется с этим. Вы не хотите зацикливаться на клиентах или создавать несколько утверждений, которые я предполагаю (не идеально)? – user3366016

+0

@ user3366016 Я не видел этого сообщения. Благодаря! Я предполагаю, что поиск по ключевым словам не так хорош, как я думал ... И нет, я не хочу цитировать несколько операторов, потому что это займет слишком много времени на сотнях тысяч предметов. – Slpk

ответ

0

Итак, я обнаружил, что не было смысла продолжать использовать ActiveRecord, так как я не использовал его, поэтому решил придерживаться Mysql2::Client.

Просто убедитесь, что flags: Mysql2::Client::MULTI_STATEMENTS установлен и не забудьте очистить результаты всех предыдущих команд перед выдачей другой:

while client.next_result 
end 

Кроме того, причиной пытается использовать ActiveRecord было управление транзакциями. Можно сделать то же самое с:

client.query 'BEGIN' 
client.query 'COMMIT' 
client.query 'ROLLBACK'