用于将多个CSV文件导入MySQL数据库的Perl脚本

时间:2015-10-23 21:11:14

标签: 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/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()

1 个答案:

答案 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命令。