Помимо проблемы с кодировкой, я не думаю, что есть какая-либо гарантия, что values
всегда будет давать поля в одном и том же порядке. Возможно, вы получаете различный хэш-адрес от fetchrow_hashref
каждый раз, когда вызываете его. Решение этой проблемы заключается в использовании fetchrow_arrayref
.
Текст :: CSV рекомендует Текст :: CSV :: Кодированный :
my $csv = Text::CSV::Encoded->new({ eol => "\015\012" });
open my $fh, '>:raw', 'Foo.csv';
my $sth = $dbh->prepare("SELECT * FROM Foo");
$sth->execute();
$csv->print($fh, $sth->{NAME_lc}); # or NAME or NAME_uc
while (my $row = $sth->fetchrow_arrayref) {
$csv->print($fh, $row);
}
Или, если вы не хотите устанавливать новый модуль:
use Encode 'find_encoding';
my $utf8 = find_encoding('utf8');
my $csv = Text::CSV->new({ binary => 1, eol => "\015\012" });
open my $fh, '>:raw', 'Foo.csv';
my $sth = $dbh->prepare("SELECT * FROM Foo");
$sth->execute();
# I'm assuming your field names are ASCII:
$csv->print($fh, $sth->{NAME_lc}); # or NAME or NAME_uc
while (my $row = $sth->fetchrow_arrayref) {
$csv->print($fh, [ map { $utf8->encode($_) } @$row ]);
}