我有这个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/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";
它在$load->execute($file)
给出了错误,因为它无法找到该文件,但我已经在代码的早期@file
加载了所有内容。
编辑: 由于暗示建议,我现在更干净,但我无法找到将当前文件放入查询(令牌)的方法,在尝试之下但却出错:
for my $file (@files) {
my $statement = $dbh->prepare("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)");
$statement->execute()
答案 0 :(得分:2)
主要问题是,当您提供相对路径时,LOAD DATA INFILE
的行为看起来并不直观。
如果未指定
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)
});
}
如果这不起作用,我可能只需print
语句并将它们输入mysql
命令。