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 => 0
しFile::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;