将SQL查询导出为CSV的Perl脚本

3
以下代码可以正常使用,但是在Excel中打开时所有数据都会显示在一行中(但不同列)。查询应该显示数据标题、第1行和第2行。此外,当我打开文件时,会出现一个警告,显示“您正在尝试打开的文件‘xxxx.csv’与文件扩展名指定的格式不同。请验证文件没有损坏......等。你想现在打开这个文件吗?”如何解决?这可能也是问题的原因。
简而言之,在导出csv时需要多行而不仅仅是一行。修复Excel错误。谢谢!
#!/usr/bin/perl
use warnings;
use DBI;
use Text::CSV;


# local time variables
($sec,$min,$hr,$mday,$mon,$year) = localtime(time);
$mon++;
$year += 1900;

# set name of database to connect to
$database=MDLSDB1;

# connection to the database
my $dbh = DBI->connect("dbi:Oracle:$database", "", "")
or die "Can't make database connect: $DBI::errstr\n";

# some settings that you usually want for oracle 10 
$dbh->{LongReadLen} = 65535; 
$dbh->{PrintError} = 0;  

# sql statement to run
$sql="select * from eg.well where rownum < 3";

my $sth = $dbh->prepare($sql);
$sth->execute();


my $csv = Text::CSV->new ( { binary => 1 } )             
or die "Cannot use CSV: ".Text::CSV->error_diag (); 

open my $fh, ">:raw", "results-$year-$mon-$mday-$hr.$min.$sec.csv"; 

$csv->print($fh, $sth->{NAME});

while(my $row = $sth->fetchrow_arrayref){      

$csv->print($fh, $row);
}

close $fh or die "Failed to write CSV: $!"; 

2
首先,您正在尝试将数组引用打印到文件句柄...这将导致类似于“ARRAY(0x323523)”等的行。不要相信Excel。不要害怕实际查看csv文件的内容(通过catvi等)。 - user554546
此外,您完全没有错误检查,因此无法确定是否已成功连接到数据库,表eg.well是否存在,查询是否成功完成,是否返回了零行等。 - user554546
此外,除非你正在编写一行代码,否则你应该使用 use strict - user554546
好的,我会确保做到。为了辩护,我昨天才开始学习Perl,并且使用了谷歌来帮助哈哈。 - Scuba_Steve
2个回答

11
while(my $row = $sth->fetchrow_arrayref){   
  $csv->print($fh, $row);
  $csv->print($fh, "\n");
}

CSV的行是通过换行符分隔的。只需在每一行后面添加一个换行符即可。


2
我得到了下一个错误:期望字段是一个数组引用,位于...处的$csv->print($fh, "\n"); - Eugen Konkov
2
@EugenKonkov:那一行应该是print $fh "\n";,因为$csv对象期望一个包含要打印的行的数组。我提交了一个编辑,但需要审核。 - Hans Goldman

2

我认为另一个解决方案是使用 Text::CSV 对象的实例化,并在那里传递所需的行终止符...

my $csv = Text::CSV->new ( { binary => 1 } )             
  or die "Cannot use CSV: " . Text::CSV->error_diag();

成为:

my $csv = Text::CSV->new({ binary => 1, eol => "\r\n" })
  or die "Cannot use CSV: " . Text::CSV->error_diag();

这是正确的解决方案。将 MySQL 导出为 CSV 的查询需要定义如何用 \r\n 终止行。如果您在设置二进制标志后没有包括 "eol => "\r\n",则在导出时,您会发现第一行数据与标题合并为一个单独的行。您还需要删除 $fh "\n" 的打印行,否则您每行数据之间会有空白行。 - TechDex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接