我尝试使用以下Perl脚本将SQL查询的结果写入CSV文件:
#!/usr/bin/perl
#
use DBI;
use Text::CSV_XS;
use strict;
my $dbh = DBI->connect('DBI:mysql:dbname', 'username', 'password') ||
die "Cannot connect to database\n", $DBI::errstr;
my $sth = $dbh->prepare("SELECT g.factGroupName, b.CI, a.Config
FROM alpha a
INNER JOIN beta b ON a.TypeId = b.MetricType
INNER JOIN gamma g ON g.factGroupId = b.Factgroup
WHERE a.ToolName = 2 AND a.TypeName = 'inputs.conf' AND a.Deploy = 'Y'");
$sth->execute || die "failed to execute:\n ", $DBI::errstr;
my $csv = Text::CSV_XS->new({ 'quote_char' => '"',
'escape_char' => '"',
'sep_char' => ',',
'binary' => 0,
'eol' => "\r\n"
});
open (my $FH, '>', '/home/XXXXX/inputs.csv') || die "Cannot open file\n";
while (my @row = $sth->fetchrow_array) {
if ($csv->combine(@row)) {
print $csv->string;
} else {
my $err = $csv->error_input;
print "combine() failed on argument: ", $err, "\r\n";
}
}
close $FH;
$dbh->disconnect;
当我执行脚本时,这是我在显示器上收到的输出:
oem,/opt/oracle/product/gc_inst1/em/EMGC_OMS*/sysman/log/emctl.log,"sourcetype=servicelog2,index=oem_prod"
oem,/opt/oracle/product/gc_inst1/em/EMGC_OMS*/sysman/log/emoms.log,"sourcetype=servicelog2,index=oem_prod"
oem,/opt/oracle/product/gc_inst1/user_projects/domains/GCDomain/servers/EMGC_OMS*/logs/EMGC_OMS*.log,"sourcetype=Bealog,index=oem_prod"
唯一的问题是,它没有写入我在脚本中引用的inputs.csv;该文件存在于给定目录中,但文件大小为零。
另一个问题是,在每行输出中返回的第三个字段(" a.Config")都有双引号,我想在它写入之前将其删除CSV文件。该字段包含两个以逗号分隔的字符串,并使用MySQL数据库中的GLOB配置存储,不使用引号;我的猜测是DBI查询正在添加双引号作为其操作的一部分。
非常感谢任何帮助!
答案 0 :(得分:1)
您需要告诉Text :: CSV_XS它应该写入您的文件。
if ($csv->combine(@row)) {
print $csv->string;
}
这将打印到屏幕上。而是打印到$FH
。
if ($csv->combine(@row)) {
print $FH $csv->string;
}
最好直接使用$csv->print
因为效率更高。
$csv->print($FH, \@row);
在这种情况下,error_input
为undef
,因此您无法使用它来显示调试信息。
我不认为那些来自数据库。您将escape_char
设置为"
,数据中包含逗号,
,因此Text :: CSV_XS会在值周围正确添加引号。如果您不想这样做,但实际上想要将$row[2]
中的值视为多个值,请在逗号上split
。
while (my @row = $sth->fetchrow_array) {
$csv->print($FH, [ @row[0, 1], split /,/, $row[2] ] );
}
@row[1, 2]
是一个数组切片。它与说$row[0], $row[1]
相同。