Массив столбцов рецептов Perl DBI
Ниже мой вывод SQL-запроса
Company Col1 Col2 Col3
Comp1 1 2 3
Comp2 4 5 6
Comp3 7 8 9
Процедура Perl для подключения и получения результатов
my $query1= qq(select * from database_table);
my $result1 = $dbh->selectall_arrayref($query1, {Slice => {}});
my %result1 =
map { shift @$_, [ @$_ ]}
@{$dbh->selectall_arrayref($query1)};
my @json_output = map { encode_json( { 'name' => $_, 'data'=> $result1{$_} } )
} sort keys %result1 ;
print Dumper %result1;
[{"name":"Comp1","data":[1,2,3]}, {"name":"Comp2","data":[4,5,6]}, {"name":"Comp3","data":[7,8,9]}]
Я читал http://www.perlmonks.org/?node_id=284436, но я не мог понять, как хранить значения столбцов в качестве элементов массива. (Как показано ниже)
[{"name":"Col1","data":[1,4,7]}, {"name":"col2","data":[2,5,8]}, {"name":"col3","data":[3,6,9]}]
Кроме того, поля значений по умолчанию в json представлены как "string", есть ли рекомендации по их преобразованию в числа?
2 ответа
Вот как бы это было
use strict;
use warnings;
use DBI;
use DBD::mysql;
use JSON;
use Data::Dumper;
my $dbh = DBI->connect('DBI:mysql:dbnew:localhost');
my $query1=qq(select * from database_table);
my $sth=$dbh->prepare($query1);
$sth->execute;
my @col_names=@{$sth->{NAME}};
my %result1;
for(my $i=0;$i<3;$i++)
{
my @res = map { $_->[$i]} @{$dbh->selectall_arrayref($query1)};
@res=map {$_ * 1} @res;
$result1{shift @col_names}=\@res;
}
my @json_output = map {encode_json( { 'name' => $_ , 'data'=> $result1{$_} } )} sort keys %result1;
print @json_output;
Предполагая, что у меня есть таблица, как вы показали, но она называется "фм".
use DBI;
use strict;
use warnings;
use Data::Dumper;
use JSON::XS;
my $h = DBI->connect('dbi:ODBC:xxx', 'xxx', 'xxx');
my $r = $h->selectall_arrayref(q/select company, col1, col2, col3 from fm/);
print Dumper($r);
my @to_encode;
foreach my $row (@$r) {
my $hash;
$hash->{name} = shift @$row;
$hash->{data} = $row;
push @to_encode, $hash;
}
my $js = encode_json(\@to_encode);
print Dumper($js);
выходы:
$VAR1 = [
[
'comp1',
'1',
'2',
'3'
],
[
'comp2',
'4',
'5',
'6'
],
[
'comp3',
'7',
'8',
'9'
]
];
$VAR1 = '[{"name":"comp1","data":["1","2","3"]},{"name":"comp2","data":["4","5","6"]},{"name":"comp3","data":["7","8","9"]}]';
РЕДАКТИРОВАТЬ: перечитайте ваш пример, и я думаю, что это действительно то, что вы хотите:
use DBI;
use strict;
use warnings;
use Data::Dumper;
use JSON::XS;
my $h = DBI->connect('dbi:ODBC:baugi', 'sa', 'easysoft');
my $s = $h->prepare(q/select col1, col2, col3 from fm/);
$s->execute;
my $cols = $s->{NAME};
my @data;
for (my $n = 0; $n < scalar(@$cols); $n++) {
push @data, {name => $cols->[$n], data => []};
}
while (my @row = $s->fetchrow) {
for (my $n = 0; $n < scalar(@$cols); $n++) {
push @{$data[$n]->{data}}, shift @row;
}
}
my $js = encode_json(\@data);
print Dumper($js);
$VAR1 = '[{"name":"col1","data":["1","4","7"]},{"name":"col2","data":["2","5","8"]},{"name":"col3","data":["3","6","9"]}]';
Возможно, есть гораздо более элегантные способы сделать это и упростить работу Perl с помощью лучшего SQL, но это рано, и я еще не выпил свой первый кофе.
Как вы указали, числа выглядят как строки в кодированном JSON. Это потому, что ваш модуль JSON (ну, в любом случае, JSON::XS) использует что-то вроде sv_POK в скалярах, чтобы попытаться угадать, являются ли они числами или строками, и большинство модулей DBD связывают все столбцы как строки и устанавливают возвращаемый скаляр с помощью sv_setpv. Это раздражает, но вам нужно будет добавить 0 к каждому номеру перед вызовом encode_json ИЛИ:
По чистой случайности я просто меняю DBD::ODBC, поэтому он будет связывать целые числа как целые числа - см. Основные изменения в связывании столбцов в Perl DBD::ODBC
С помощью DBD::Oracle вы можете связать столбцы, так как SQL_INTEGER добавляет атрибут DiscardString, например,
$s->prepare(q/select company,col1,col2,col3 from mytable);
$s->execute;
$s->bind_col(2, undef, {TYPE => SQL_INTEGER, DiscardString => 1});
# repeat for col2 and col3
$r = $s->fetchall_arrayref
Я полагаю, что некоторые другие DBD уже связывают целые числа как целые числа - это может быть DBD::Pg.