1

こんにちは私は次のperlスクリプトを実行してcsvファイルを既存のmysqlデータベーステーブルにインポートしようとするとエラーが発生し続けます。実行するたびに、「Died at /home/perl/dep_import_2.plline10」というメッセージが表示されます。

どんな助けでもいただければ幸いです

ありがとう

#!/usr/bin/perl

use DBI;
use DBD::mysql;
use warnings "all";


if ($#ARGV != 0) {
   print "Usage: dep_import_2.pl filename\n";
     die;
}
$filename = $ARGV[0];


# MySQL CONFIG VARIABLES
$host = "localhost";
$user = "standard";
$pw = "standard";

$database = "data_track";
$dsn = "DBI:mysql:database=" . $database . ";host=" . $host;

$dbh = DBI->connect($dsn, $user, $pw)
   or die "Can't connect to the DB: $DBI::errstr\n";

print "Connected to DB!\n";

open FILE, "/home/dep/new_study_forms_2.csv", $filename or die $!;

$_ = <FILE>;
$_ = <FILE>;

while (<FILE>) {
    @f = split(/,/, $_);

    $sql = "INSERT INTO dep (date, subject, weight, size, time, hi_pre, hi_post, hi_afternoon, hi_test, actical_on, actical_off, saggital_1, saggital_2, crown_heel1, crown_heel2, crown_rump1, crown_rump2, scan, record_number, tap, sample, dye, left_chip, right_chip) VALUES('$f[0]', '$f[1]', '$f[2]', '$f[3]' '$f[4]', '$f[5]', '$f[6]', '$f[7]', '$f[8]', '$f[9]', '$f[10]', '$f[11]', '$f[12]', '$f[13]', '$f[14]', '$f[15]', '$f[16]', '$f[17]', '$f[18]', '$f[19]', '$f[20]', '$f[21]', '$f[22]', '$f[23]')";
    print "$sql\n";
    my $query = $dbh->do($sql);
}
4

2 に答える 2

4

コードにはいくつかの問題があります。まず、そして最も重要なことは、あなたが使用していないことです

use strict;
use warnings;

コード内のエラーに関する情報が得られないため、これは悪いことです。

他の人が指摘しているように、スクリプトが死ぬ理由$#ARGVはゼロではないからです。スクリプトに渡した引数が少なすぎるか多すぎることを意味します。使用法ステートメントが示すように、スクリプトへの引数は正確に 1 でなければなりません。

ただし、以下のオープンステートメントが台無しになっているため、それでは問題は解決しません。ファイル名を直接追加しようとしたと思います。この行:

open FILE, "/home/dep/new_study_forms_2.csv", $filename or die $!;

おそらくエラーが発生しますunknown open() mode ...。それはおそらく

open FILE, "<", $filename or die $!;

そして、それが/home/dep/new_study_forms_2.csv使用する正しいファイルであると仮定して、コマンド ラインでスクリプトに渡します。

また、 DBIのドキュメントで説明されているように、クエリ文字列では、変数を補間しないでください。プレースホルダーを使用する必要があります。プレースホルダーが引用を処理し、データの破損を防ぎます。クエリ行をもう少し単純にするために、次のようなことができます:

my $sth = $dbh->prepare(
    "INSERT INTO dep (date, subject, weight, size, time, hi_pre, hi_post, 
     hi_afternoon, hi_test, actical_on, actical_off, saggital_1, saggital_2,
     crown_heel1, crown_heel2, crown_rump1, crown_rump2, scan, record_number, 
     tap, sample, dye, left_chip, right_chip) 
     VALUES(" . join(",", ("?") x @f) . ")");
$sth->execute(@f);
于 2012-12-10T20:32:38.720 に答える
3

これは、 Text::CSVを使用してCSVを適切に解析するスクリプトです。最初の行に列名が含まれていることを前提とし、CSVをバッチでロードし、100回の挿入ごとにコミットします。すべてのパラメーター(ユーザー、パスワード、データベース)は、コマンドラインオプションを使用して構成できます。使用法はインラインPODドキュメントです。

#!/usr/bin/env perl
use strict;
use warnings qw(all);

use DBI;
use Getopt::Long;
use Pod::Usage;
use Text::CSV_XS;

=pod

=head1 SYNOPSIS

    dep_import_2.pl --filename=file.csv --host=localhost --user=standard --pw=standard --database=data_track

=head1 DESCRIPTION

Loads a CSV file into the specified MySQL database.

=cut

my $host = 'localhost';
my $user = 'standard';
my $pw = 'standard';
my $database = 'data_track';
my $commit = 100;

GetOptions(
    'help'          => \my $help,
    'filename=s'    => \my $filename,
    'host=s'        => \$host,
    'user=s'        => \$user,
    'pw=s'          => \$pw,
    'database=s'    => \$database,
    'commit=i'      => \$commit,
) or pod2usage(q(-verbose) => 1);
pod2usage(q(-verbose) => 2) if $help;

my $dbh = DBI->connect("DBI:mysql:database=$database;host=$host", $user => $pw)
    or die "Can't connect to the DB: $DBI::errstr";

my $csv = Text::CSV_XS->new
    or die "Text::CSV error: " . Text::CSV->error_diag;

open(my $fh, '<:utf8', $filename)
    or die "Can't open $filename: $!";

my @cols = @{$csv->getline($fh)};
$csv->column_names(\@cols);

my $query = "INSERT INTO dep (@{[ join ',', @cols ]}) VALUES (@{[ join ',', ('?') x (scalar @cols) ]})";
my $sth = $dbh->prepare($query);

my $i = 0;
while (my $row = $csv->getline_hr($fh)) {
    $sth->execute(@{$row}{@cols});
    $dbh->commit if ((++$i % $commit) == 0);
}

$dbh->commit;
$dbh->disconnect;

$csv->eof or $csv->error_diag;

close $fh;
于 2012-12-11T18:25:45.650 に答える