2

LOAD DATA LOCAL INFILEステートメントを使用して、MySQL データベースにデータをロードしようとしています。通常のファイルでは、これは正常に機能します。

で一時ファイルを作成した場合File::Temp、CSV データをその中に保存し、ファイルを閉じてからLOAD

$dbh->do("LOAD DATA LOCAL INFILE '$tempfile' INTO TABLE $temptable" FIELDS TERMINATED BY ',');

最後の 2 つのレコードは再現可能に省略されています。ただし、作成と ing の間に一時ファイルを使用して何かを行うと、LOADたとえば 次のようになります。

`touch $tempfile`;

すべてが期待どおりに機能します。

これは、新しく作成された一時ファイルに問題がある MySQL ドライバーの問題ですか? ファイルシステム (ext4) の問題ですか? キャッシュ フラッシュが間に合わない可能性がありますか? ここで何か不足していますか?

EDIT : 実際には、一時 CSV ファイルがフォーマット コンバーター サブルーチンによって作成されたのではなく、以下に示すように手動で作成された場合、すべてのレコードが省略されます。データベースとのやり取りのコードも含めました。コメントされていることに注意してください。コメントtouch $tmpfhを外すと、例が機能します。

に追加UNLINK => 0File::Temp->new()ても違いはありません。

my $tmpfh = File::Temp->new();
print $tmpfh <<EOT;
record1,textfield1
record2,textfield2
record3,textfield3
record4,textfield4
record5,textfield5
EOT

# `touch $tmpfh`; # uncomment this line to make it work

# get db handle
my $dbh = DBI->connect("DBI:mysql:$dbname:$dbserver", $username, $pwd);

# drop and recreate temp table
$dbh->do("DROP TABLE IF EXISTS $temptable") or die;
$dbh->do("CREATE TABLE $temptable (
`id`       INT(11)      NOT NULL PRIMARY KEY AUTO_INCREMENT,
`header`   VARCHAR(255) NOT NULL,
`sequence` MEDIUMBLOB)")
    or die;

# load data into temp table
my $nrecords = $dbh->do("LOAD DATA LOCAL INFILE '$tmpfh' 
INTO TABLE $temptable 
FIELDS TERMINATED BY ',' 
(header, sequence)")
    or die;

$dbh->disconnect();

printf "Loaded %d records from %s into %s on %s.\n", $nrecords, $tmpfh, $dbname, $dbserver;
4

1 に答える 1

3

ファイル ハンドルを閉じてバッファをフラッシュします。オブジェクトが範囲外になったときにファイルを残したい場合は、「UNLINK => 0」を保持します。

于 2012-04-24T16:51:01.313 に答える