あなたが示したように、「fm」と呼ばれるテーブルがあると仮定します。
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"]}]';
それを実行し、より優れた SQL を使用して Perl の作業を単純化する、もっと洗練された方法があるかもしれませんが、それは時期尚早で、私はまだ最初のコーヒーを飲んでいません。
ご指摘のとおり、数値はエンコードされた JSON の文字列のように見えます。これは、JSON モジュール (とにかく JSON::XS) がスカラーに対して sv_POK のようなものを使用して、それらが数値か文字列かを推測し、ほとんどの DBD モジュールがすべての列を文字列としてバインドし、返されたスカラーを sv_setpv で設定するためです。面倒ですが、encode_json を呼び出す前に各数値に 0 を追加する必要があります OR:
たまたま 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 かもしれません。