0

我希望将 600 多个 txt 文件导入 MySQL,并希望使用 perl 和以下代码,但它似乎不起作用。从某种意义上说,它连接,然后断开连接,但似乎没有按照说明打开每个文件和处理,所以我的导入表仍然是空的。该目录存在,因此除非我的代码中存在明显错误,否则不确定可能出现什么问题。当我执行 perl 脚本时,我没有收到任何错误消息。每个文件每行有一个记录,用 \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.";
4

1 回答 1

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";
于 2012-11-29T12:35:19.110 回答