将多个CSV文件导入MySQL数据库的Perl脚本
我有一个Perl脚本:将多个CSV文件导入MySQL数据库的Perl脚本,mysql,perl,csv,Mysql,Perl,Csv,我有一个Perl脚本: use v5.12; use strict; use warnings; use DBI; my $dsn = "DBI:mysql:host=localhost;database=testitt"; my $dbh = DBI->connect($dsn,"root","") or die "No db connectin: $!"; say "Connected to MySQL."; my $source_dir = "C:/Users/S
use v5.12;
use strict;
use warnings;
use DBI;
my $dsn = "DBI:mysql:host=localhost;database=testitt";
my $dbh = DBI->connect($dsn,"root","")
or die "No db connectin: $!";
say "Connected to MySQL.";
my $source_dir = "C:/Users/ST/Desktop/";
opendir my $dirh, $source_dir or die "Unable to open directory: $!";
my @files = grep /\.csv$/i, readdir $dirh;
closedir $dirh;
die "No files found in $source_dir" unless @files;
say 'Importing data from:';
say for @files;
my $load = $dbh->prepare("LOAD DATA INFILE ? INTO TABLE tablea Character Set utf8 FIELDS TERMINATED BY ' ' LINES TERMINATED BY '\n' IGNORE 1 LINES (id, normalized_count)")
or die "Prepare failed: " . $dbh->errstr();
for my $file (@files) {
say "Processing $source_dir/$file";
open my $fh, '<', "$source_dir/$file"
or die "Unable to open $source_dir/$file: $!\n";
$load->execute($file)
or die "Execute failed: " . $dbh->errstr();
}
print "Jobs done.\n";
主要的问题是,当您提供相对路径时,它的行为看起来并不是直观的明显,而您正是这样做的 如果未指定
LOCAL
,则文件必须位于服务器上
主机,并由服务器直接读取。服务器使用以下命令
查找文件的规则:
- 如果文件名是绝对路径名,服务器将按给定方式使用它
- 如果文件名是具有一个或多个前导组件的相对路径名,则服务器将相对于服务器的路径名搜索该文件 数据目录
- 如果给定的文件名没有前导组件,则服务器将在默认组件的数据库目录中查找该文件 数据库
关于你的编辑,我注意到了几个问题。您需要引用整个路径,我坚持使用前斜杠,如下所示:
for my $file (@files) {
$dbh->do(qq{
LOAD DATA INFILE 'C:/Users/ST/Desktop/$file' INTO TABLE rnaseq
CHARACTER SET utf8
FIELDS TERMINATED BY ' '
LINES TERMINATED BY '\\n'
IGNORE 1 LINES (id, normalized_count)
});
}
如果这不起作用,我可能只需
打印
语句,并将它们导入mysql
命令。一些事情:1。您不需要在循环中打开每个文件进行读取(MySQL正在完成这一部分)。2.你能用占位符吗?3.您应该为文件名使用绝对路径,否则“服务器将在默认数据库的数据库目录中查找文件”(),谢谢。不过,我仍然不能100%确定占位符是否也会导致问题。From:对于大多数驱动程序,占位符不能用于语句的任何元素,这将阻止数据库服务器验证该语句并为其创建查询执行计划。它是否阻止服务器在此处执行此操作?呃。。。我不知道。嗨,马特。谢谢你的帮助。非常感谢。不幸的是,我不知道如何应用你的建议,所以如果你能更具体一些,那将对我有很大帮助。谢谢。@BlueStarry在open()
(顺便说一句,这不是必需的):“$source\u dir/$file”
中构建绝对路径时,您已经做了正确的事情。唯一的问题是Windows上的MySQL是否可以处理正向斜杠,但我认为应该。也许我的英语不好,但我不理解:首先你说你不需要开放式,然后你质疑相对路径,然后你告诉我你在开放式中使用绝对路径是正确的,但这不是必要的,但仍然是,脚本不起作用。您不需要open()
。2.您应该提供加载数据填充的绝对路径,就像您在其他3个地方所做的那样。
for my $file (@files) {
$dbh->do(qq{
LOAD DATA INFILE 'C:/Users/ST/Desktop/$file' INTO TABLE rnaseq
CHARACTER SET utf8
FIELDS TERMINATED BY ' '
LINES TERMINATED BY '\\n'
IGNORE 1 LINES (id, normalized_count)
});
}