您好我在尝试运行以下perl脚本以将csv文件导入现有的mysql数据库表时遇到错误。每次我运行它时都会收到消息“死于/home/perl/dep_import_2.pl第10行。
任何帮助将不胜感激
由于
#!/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);
}
答案 0 :(得分:4)
您的代码存在一些问题。首先,最重要的是,你没有使用
use strict;
use warnings;
这很糟糕,因为没有它们,您将无法获得有关代码中错误的信息。
正如其他人所指出的,脚本死亡的原因是因为$#ARGV
不是零。这意味着您要么向脚本传递的参数太少或太多。脚本的参数必须正好一个,就像使用声明所说的那样。
但是,这不会解决您的问题,因为下面的公开声明搞砸了。我的猜测是你试图直接添加你的文件名。这一行:
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
传递给命令行上的脚本,假设这是正确的文件。
此外,在查询字符串中,不应插入变量,应使用占位符,如documentation for 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);
答案 1 :(得分: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;