2013-10-13 3 views
3

Я пытаюсь использовать запрос базы данных для вывода запроса на печать в CSV, но не может выводить вывод на отдельные строки. Как это сделать?Запись из базы данных с использованием Perl Text :: 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: $!"; 

Это должно быть общее использование дело, но не смогли найти ничего о проблемах с новыми линиями.

+0

Вы используете '()' 'внутри QQ()', что довольно странно (но, кажется, работает по какой-то причине!), А не с запятой на конце линии , что должно привести к синтаксической ошибке. Вы никогда не должны по какой-либо причине пытаться ввести свой исходный код в вопрос: всегда вырезать и вставлять. – TLP

+0

с запятой добавлено! Кодекс должен был быть анонимным/обобщенным, чтобы иметь смысл. Резка и вставка фактического кода не сработала бы. В северном направлении скобки в выражениях MySQL, ограниченные или не ограниченные qq(), всегда работают для меня! – user1849286

+1

С 'qq()' (и многие другие perl-операторы, такие как 'm //', 's ///', 'qr //' и т. Д.), Вы можете изменить круглые скобки почти на любой другой символ пунктуации. Это уменьшает необходимость в escape-символах, таких как 'm/\/usr \/bin \ //' может быть 'm #/usr/bin/#'. Но в этом случае кажется, что 'qq()' может обрабатывать круглые скобки * внутри *, только до тех пор, пока они сбалансированы. Я не знал этого. Один из тех крайних случаев, которые я не уверен, действительно полезен, но интересный кусочек мелочей. :) – TLP

ответ

-1

попробовать этот запрос будет

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

Я полагаю, ваша проблема в том, что все ваши данные CSV заканчивается на той же линии?

Вы должны установить опцию eol в вашем объекте CSV:

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 принимает массив ref. Использование ссылок будет более простым.

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

Прежде всего, у Вас есть недостающая точка с запятой в конце строки

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" }); 

или просто напечатать строку в явном виде, как это. Обратите внимание, что нет необходимости извлекать строку в массив, а затем копировать ее в анонимный массив, чтобы заставить это работать. fetchrow_arrayref вернет ссылку на массив, которую вы можете просто передать непосредственно print.

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

@TLP: Надеюсь, вы не серьезно? – Borodin

Смежные вопросы