【问题标题】:Write from database using Perl Text::CSV使用 Perl Text::CSV 从数据库写入
【发布时间】:2013-10-21 10:16:26
【问题描述】:

我正在尝试使用数据库查询将查询输出打印到 CSV,但无法将输出输出到单独的行。该怎么做?

代码如下:

use warnings;
use DBI;
use strict;
use Text::CSV;

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

open my $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!";

#set up query
my $dbh = DBI->connect("DBI:mysql:db", "name") or die ("Error:  $DBI::errstr");

my $sql = qq(select * from one_table join two_table using (primary_key));
my $query = $dbh->prepare($sql);
$query->execute;

#loop through returned rows of query and save each row as an array
while ( my (@row ) = $query->fetchrow_array ) {
    #print each row to the csv file
    $csv->print ($fh, [@row]);    
        # every line seems to be appended to same line in "new.csv"
        # tried adding "\n" to no avail 
    }
close $fh or die "new.csv: $!";

这一定是一个常见的用例,但找不到任何关于新行问题的信息。

【问题讨论】:

  • 您在qq() 中使用(),这很奇怪(但似乎出于某种原因可以使用!),并且行尾没有分号,这应该会导致语法错误。无论出于何种原因,您都不应该尝试将您的源代码输入一个问题:始终剪切和粘贴。
  • 添加了分号!代码必须匿名/通用化才能有意义。剪切和粘贴实际代码是行不通的。 NB。 MySQL 语句中的括号是否由 qq() 限制似乎总是对我有用!
  • 使用 qq()(以及许多其他 perl 运算符,例如 m//s///qr// 等),您可以将括号更改为几乎任何其他标点符号。这减少了转义字符的需要,例如m/\/usr\/bin\// 可能是m#/usr/bin/#。但是在这种情况下,qq() 似乎可以处理 inside 的括号,只要它们是平衡的。我不知道。其中一个我不确定是否真的有用的边缘案例,但是一个有趣的琐事。 :)

标签: perl csv


【解决方案1】:

我假设您的问题是所有 CSV 数据都在同一行结束?

您应该在 CSV 对象中设置 eol 选项:

my $csv = Text::CSV->new ( {
         binary => 1,      # should set binary attribute.
         eol    => $/,     # end of line character
}) or die "Cannot use CSV: ".Text::CSV->error_diag ();

此字符将附加到print 的行尾。您也可以考虑不要在每次迭代时都从 fetchrow 调用中复制值,因为 print 需要一个数组引用。使用引用会更直接。

while (my $row = $query->fetchrow_arrayref) {
    ....
    $csv->print($fh, $row);

【讨论】:

    【解决方案2】:

    首先,你在行尾缺少一个分号

    my $sql = qq(select * from one_table join two_table using (primary_key))
    

    默认情况下,Text::CSV 使用$\ 的当前值,即行尾的输出记录分隔符。而且,默认情况下,它设置为undef,因此您不会打印任何分隔符。

    你可以或者设置你的$csv对象

    my $csv = Text::CSV->new({ binary => 1, eol => "\n" });
    

    or 像这样显式地打印换行符。请注意,无需将行提取到数组中,然后将其复制到匿名数组即可使其正常工作。 fetchrow_arrayref 将返回一个数组引用,您可以直接将其传递给 print

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

    【讨论】:

    • @TLP:希望你不是认真的?
    【解决方案3】:

    试试这个 sql 查询

    select * from one_table join two_table using (primary_key) 
    INTO OUTFILE '/tmp/new.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 2011-09-30
      • 2011-05-08
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多