2012-06-01 61 views
2

下面的代码有效,但在Excel中打开时,所有数据都显示在一行(但不同的列)中。查询应该显示数据标题,第1行和第2行。另外,当我打开文件时,我收到一条警告,提示“你试图打开的文件'xxxx.csv'的格式与由文件扩展名指定,确认文件没有被破坏,等等。你现在想打开文件吗?“无论如何解决这个问题?这也可能是原因。用于将sql查询导出到csv的Perl脚本

tldr;导出到多行的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文件的内容(通过'cat','vi'等)。 – 2012-06-01 20:36:37

+0

此外,您完全没有错误检查,所以您无法判断您是否已成功连接到数据库,表是否存在'eg.well',查询是否成功完成,是否返回零行,等等。 – 2012-06-01 20:39:47

+0

此外,除非你编写一个不需要的单行代码,否则你应该“严格使用”。 – 2012-06-01 20:42:48

回答

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

CSV行由换行分隔。只需在每行之后添加一个换行符。

+1

我得到下一个错误:预期字段是一个数组参考在......为'$ csv-> print($ fh,“\ n”);'' –

+1

@EugenKonkov:该行应该是'print $ fh“\ n”;'因为$ csv对象期望有一个包含要打印的行的数组。我提交了一个编辑,但需要审查。 –

0

我觉得另一种解决方案是使用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();