SQL::Abstract::Plugin::InsertMulti
作ってみました。元ネタは MySQLにおけるbulk insert と bulk update - 金利0無利息キャッシング – キャッシングできます - subtech です。bulk insert, bulk update *1 が出来ます。
- SQL-Abstract-Plugin-InsertMulti-0.05 - add mysql bulk insert supports for SQL::Abstract - metacpan.org
- GitHub - zigorou/p5-sql-abstract-plugin-insertmulti: bulk insert and update support for SQL::Abstract
使い方は非常に簡単で、t/01_basic.t とか見て頂けるとすぐ分かるかと思いますがこんな感じです。
use strict; use warnings; use Data::Dump qw(dump); use Perl6::Say; use SQL::Abstract; use SQL::Abstract::Plugin::InsertMulti; my $sql = SQL::Abstract->new; my ($stmt, @bind) = $sql->insert_multi( 'app_data', [qw/app_id guid name value created_on updated_on/], [ [1, 1, 'score', 100, \'UNIX_TIMESTAMP()', \'UNIX_TIMESTAMP()'], [1, 1, 'ranking', 3, \'UNIX_TIMESTAMP()', \'UNIX_TIMESTAMP()'], [1, 2, 'score', 200, \'UNIX_TIMESTAMP()', \'UNIX_TIMESTAMP()'], [1, 2, 'ranking', 2, \'UNIX_TIMESTAMP()', \'UNIX_TIMESTAMP()'], [1, 3, 'score', 300, \'UNIX_TIMESTAMP()', \'UNIX_TIMESTAMP()'], [1, 3, 'ranking', 1, \'UNIX_TIMESTAMP()', \'UNIX_TIMESTAMP()'], ], ); say dump($stmt, \@bind);
とか実行すると、
( "INSERT INTO app_data ( app_id, guid, name, value, created_on, updated_on ) VALUES ( ?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() ), ( ?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() ), ( ?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() ), ( ?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() ), ( ?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() ), ( ?, ?, ?, ?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP() )", [ 1, 1, "score", 100, 1, 1, "ranking", 3, 1, 2, "score", 200, 1, 2, "ranking", 2, 1, 3, "score", 300, 1, 3, "ranking", 1, ], )
って感じになります。その後すぐに DBI の do に渡せる感じですな。
元の id:mala さんの奴のコードを丸っとパクる事から始めたんですが、結局全部書き直してしまいました。
- SQL::Abstract の値の変換 (ScalarRef ならリテラルとして扱うとかそういうの) が適用されるように直した
- ON DUPLICATE KEY UPDATE 以下のパラメータも update() の時のパラメータのように設定出来るようにした
- update_multi() の時に、元のデータのフィールドが全部適用されちゃうのがちょっと嫌だったので、除外指定出来るようにした
- SQL::Abstract::LimitOffset 使ってて、これが継承してる奴だから横槍入れて適用出来るようにした
とかですかね。
とりあえずテーブル名が app_data ってのに特に意味はありません。悪しからず。
*1: ON DUPLICATE KEY UPDATE を利用した INSERT