Perl打开多个文件并导入MySQL数据库

时间:2012-11-29 10:11:50

标签: mysql perl import

我希望将超过600个txt文件导入MySQL,并且希望使用perl和以下代码,但它似乎不起作用。在它连接的意义上,然后断开连接,但似乎没有按照说明打开每个文件和进程,所以我的导入表仍然是空的。目录存在,所以不确定什么可能是错误的,除非我的代码中有明显的错误。执行perl脚本时,我没有收到任何错误消息。每个文件每行有一个reecord,\ n字符表示记录的结尾。我希望有人可以提供帮助,这个小问题令人困惑,我看不出任何明显的原因,为什么它不起作用。

use strict;
use warnings;
use DBI;

# Set datasource
my $dsn = "DBI:mysql:host=somehost;database=somedb"
        . ";port=someport";

# Connect to database 
my $dbh = DBI->connect($dsn,"someuser","somepassword");
print "Status: Connected to MySQL.\n";

my $dir = "t:\\some directory";

opendir (DIR, $dir) or die "Unable to open directory";
my @files = grep /\.txt/, readdir(DIR);
closedir(DIR);

foreach my $file (@files) {
open(FH, '<', "$dir\\$file") or die "Unable to open $file - $!\n";
while (<FH>){ 
    my $data = split (/\n$/);
    my $insert = $dbh->prepare('INSERT INTO sometable 
            (TEXTDATA,SOURCEFILE) 
        VALUES (?,?)') or die "Prepare failed: " . $dbh->errstr(); 
$insert->execute($data,$file) or die "Execute failed: " . $dbh->errstr(); 
}
close(FH);
}
print "Status: Processing of complete.\n";

# Disconnect from the database
$dbh->disconnect ();
print "Status: Disconnected from MySQL.";

1 个答案:

答案 0 :(得分:0)

你正在做的一些事情已经过时了。

  • 使用正斜杠代替反斜杠作为路径分隔符。 Perl会做正确的事。
  • 如果准备声明在每次迭代时都准备好了,那么它的准备工作并不是很好。它应该在循环之外准备一次。
  • 默认情况下,新行是记录分隔符。因此,不要使用split将一行数据存储到变量中,只需将该行分配给变量即可。
  • 您不会检查您是否确实在给定路径中找到了任何文件。

我做了如下更正:

use v5.12;
use strict;
use warnings;
use DBI;

# Set datasource
my $dsn = "DBI:mysql:host=somehost;database=somedb;port=someport";

# Connect to database 
my $dbh = DBI->connect($dsn,"someuser","somepassword")
    or die "Couldn't connect to MySQL server: $!";
say "Status: Connected to MySQL.";

my $source_dir = "t:/some/directory";

# Store the handle in a variable.
opendir my $dirh, $source_dir or die "Unable to open directory: $!";
my @files = grep /\.txt$/i, readdir $dirh;
closedir $dirh;

# Stop script if there aren't any files in the list
die "No files found in $source_dir" unless @files;

# You can comment out the following two lines
# once you're sure things are working
say 'Importing data from:';
say for @files;

my $insert = $dbh->prepare('INSERT INTO sometable (TEXTDATA,SOURCEFILE) '
                           . 'VALUES (?,?)')
                           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";

    # Don't use split. Just assign the line.
    while (my $line = <$fh>) {
       $insert->execute($line,$file)
           or die "Execute failed: " . $dbh->errstr(); 
    }

    close $fh;
}
print "Status: Processing of complete.\n";