mala さんのMySQLにおけるbulk insert と bulk update - 金利0無利息キャッシング – キャッシングできます - subtechのエントリーを見て, MySQL でbulk update ができることを知り, 丁度欲しい機能だったのでとりあえず動くだけのメソッドを実装.
# User.extend BulkExecuteMethods # User.update_multi([:id, :name, :age], [[1, 'bob', 11], [2, 'mary', 21]]) # # refs # http://dev.mysql.com/doc/refman/4.1/ja/insert.html # http://subtech.g.hatena.ne.jp/mala/20090729/1248880239 module BulkExecuteMethods def update_multi(columns, values) cols = columns.map{|c| self.connection.quote_column_name(c) } ph = (['(?)'] * values.size).join(',') vals = sanitize_sql([ph, *values]) expr = cols.map{|c| "#{c}=VALUES(#{c})" }.join(',') sql = sprintf(<<-SQL, self.table_name, cols.join(','), vals, expr) INSERT INTO %s (%s) VALUES %s ON DUPLICATE KEY UPDATE %s SQL affected_rows = self.connection.update(sql) # number of updated # original affected rows = number of inserted + number of duplicated(updated) # if no error occured, number of inserted equals number of duplicated(updated) affected_rows / 2 end end
- validation 通さない
- 存在しないid を指定してしまうとinsert されてしまう上, それを特に検知しない
- update した数の算出が適当
ここからまともにしていくかと思いきや, gem があった.