-
- csvの1行目にフィールド名があること。
- 「-k」オプションで主キーを指定すること。
- 「-t」オプションでupdate先のテーブル名を指定すること。
- 読み込むcsvファイル名へのフルパスを与えること。エンコードはShiftJISが前提。
- Windows上のActivePerlで動作確認。
- 標準出力に返すので、リダイレクトしてファイルに書き出すべし。(perl csv2sql.pl -t table_name -k id,no csv_file_name > update.sql)
- ツッコミどころが多々あるんだろうけど、自分としてはこれで事足りたから公開してみるテスト。
use strict;
use warnings;
use Encode;
use IO::File;
use IO::Handle;
use Text::CSV_XS;
use Time::HiRes;
use POSIX 'strftime';
my $start_time = Time::HiRes::time;
STDOUT->autoflush(1);
STDERR->autoflush(1);
binmode(STDOUT,":encoding(shift_jis)");
binmode(STDERR,":encoding(shift_jis)");
my @pkey = ();
my $fname = '';
my $tname = '';
for (my $i = 0; $i <= $#ARGV; $i++) {
if (($ARGV[$i] eq '-k') || ($ARGV[$i] eq '-K')) {
if (defined($ARGV[$i+1])) {
if ($ARGV[$i+1] =~ /,/) {
push @pkey, split(/,/, $ARGV[$i+1]);
}
else {
push @pkey, $ARGV[$i+1];
}
}
}
elsif (($ARGV[$i] eq '-t') || ($ARGV[$i] eq '-T')) {
if (defined($ARGV[$i+1])) {
$tname = $ARGV[$i+1];
}
}
elsif (-f $ARGV[$i]) {
$fname = $ARGV[$i];
}
}
if ($fname eq '') {
die "csvファイルを指定してください。";
}
if ($#pkey < 0) {
die "insert文は未実装です。";
}
my $csv = Text::CSV_XS->new({binary => 1, always_quote => 1, eol => $/});
my $fc = IO::File->new("$fname", '<:encoding(shiftjis)') || die "can't open $fname: $!";
my $lcount = 0;
my @cols = ();
until ($fc->eof) {
my $dat = $csv->getline($fc);
if ($lcount++ == 0) {
@cols = @$dat;
}
else {
my @vals = @$dat;
my $set_phrase = '';
my $where_phrase = '';
for (my $i = 0; $i <= $#cols; $i++) {
if (grep {$_ eq $cols[$i]} @pkey) {
if ($where_phrase ne '') { $where_phrase .= ' AND '; }
if ($vals[$i] eq '\N') {
$where_phrase .= $cols[$i] . ' = NULL';
}
elsif ($vals[$i] =~ /^-?[0-9]+[0-9\.]*$/) {
$where_phrase .= $cols[$i] . ' = ' . $vals[$i];
}
else {
$where_phrase .= $cols[$i] . " = '" . $vals[$i] . "'";
}
}
else {
if ($set_phrase ne '') { $set_phrase .= ', '; }
if ($vals[$i] eq '\N') {
$set_phrase .= $cols[$i] . ' = NULL';
}
elsif ($vals[$i] =~ /^-?[0-9]+[0-9\.]*$/) {
$set_phrase .= $cols[$i] . ' = ' . $vals[$i];
}
else {
$set_phrase .= $cols[$i] . " = '" . $vals[$i] . "'";
}
}
}
print 'UPDATE ', $tname, ' SET ', $set_phrase, ' WHERE ', $where_phrase, ";\n";
}
}
close $fc;
printf(STDERR "実行時間 %0.3f\n", Time::HiRes::time - $start_time);