mysql - 在 Perl 中使用 CSV_XS 和 DBI 编写 SQL 查询结果的问题

标签 mysql perl csv dbi

我正在尝试使用以下 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 文件之前将其删除。该字段包含两个由逗号分隔的字符串,并使用 GLOB 配置存储在 MySQL 数据库中,不使用引号;我的猜测是 DBI 查询将添加双引号作为其操作的一部分。

如有任何帮助,我们将不胜感激!

最佳答案

写入文件

您需要告诉 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_inputundef,所以您不能用它来显示调试信息。

去除双引号

我不认为这些来自数据库。您将 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] 相同。

关于mysql - 在 Perl 中使用 CSV_XS 和 DBI 编写 SQL 查询结果的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42419295/

相关文章:

java - Perl 和 Java 中的多重继承是否相同?

Perl:如何从特定模式开始逐字读取文本文件?

java - 从对象列表生成 CSV

php - 使用 NodeJS 使用数据库进行实时实时更新 View

php - PDO 返回空结果

php - 我想在 sql 中选择客户和日期过滤器

mysql - 如何将多个 ID 应用于 Mysql 中的一条记录?

perl - 为什么常量不会自动继承?

java - uniVocity 解析器处理两个文件

python - 无法将数组转换为 float python