Perl, JSON, float, цитаты - PullRequest
       15

Perl, JSON, float, цитаты

0 голосов
/ 05 октября 2018

У нас есть приложение Perl, которое создает JSON из запросов к БД.К сожалению, он обрабатывает поплавки неправильно, так как он помещает двойные кавычки вокруг поплавков.

Например:

use DBI;
use JSON::MaybeXS;

my $dbs="dbi:ODBC:myconnection,myuser,mypwd,";
my @ARR=split/,/ ,$dbs;
$dbh = DBI->connect(@ARR, { PrintError=>0, RaiseError=>1,  LongReadLen=>60000}) ;
my $sql = "SELECT 'Hello there' str, '0.0123' str_flt, 0.0123 flt_sm, 10.1234 flt_lg, 1234 nt, getdate() dt";
my $sth = $dbh->prepare($sql);
$sth->execute();

my $rows = $sth->fetchall_arrayref({});

print "Structure of result is: \n\n";
my $num_fields = $sth->{NUM_OF_FIELDS};
for ( my $i=0; $i< $num_fields; $i++ ) {
    my $field = $sth->{NAME}->[$i];
    my $type = $sth->{TYPE}->[$i];
    my $precision = $sth->{PRECISION}->[$i]; # e.g. VARCHAR(50) has a precision of 50
    print "Field $field is of type $type, with precision $ precision\n";
}

$sth->finish();
$dbh->disconnect;

my $json_opts = JSON::MaybeXS->new(utf8 => 1, pretty => 1);
my $json_maybe = $json_opts->encode($rows);

print("\nJSON::MaybeXS:\n");
print($json_maybe);

Вывод выглядит следующим образом:

Structure of result is:

Field str is of type -8, with precision 11
Field str_flt is of type -8, with precision 6
Field flt_sm is of type 2, with precision 4
Field flt_lg is of type 2, with precision 6
Field nt is of type 4, with precision 10
Field dt is of type 93, with precision 23

JSON::MaybeXS:
[
   {
      "dt" : "2018-10-05 09:42:43.483",
      "nt" : 1234,
      "flt_sm" : ".0123",
      "str" : "Hello there",
      "str_flt" : "0.0123",
      "flt_lg" : "10.1234"
   }
]

Версия Perl: 5.18.2

Встроенные библиотеки JSON: JSON, JSON-Any, JSON-PP, JSON-XS, Cpanel-JSON-XS, JSON-MaybeXS, Parse-CPAN-Meta

Одна вещь, что выходные данные перемешивают поля, и каждый прогон приводит к разному порядку вJSON.Основная проблема заключается в двойных кавычках вокруг чисел с плавающей запятой, что вызывает проблемы при использовании его в другом приложении, поскольку он распознает эти поля как строки и должен анализировать их одну за другой.DBI правильно распознает типы полей, они как-то теряются при кодировании json ... Есть идеи, как это исправить?(Да, я мог бы легко исправить это с помощью регулярных выражений, но это было бы не так приятно ...)

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

Попробуйте что-то вроде этого, чтобы превратить ваши числовые поля в числа, добавив 0. Нечто подобное работало у меня однажды.Использование JSON :: XS версии 3.02.

use JSON::XS 3.02;
...
my @numfield=qw( nt flt_sm str_flt flt_lg );
for my $f (@numfield) {
  defined $$_{$f} and $$_{$f}+=0 for @$rows;
}
...
0 голосов
/ 05 октября 2018

Вот почему Cpanel :: JSON :: XS имеет Cpanel :: JSON :: XS :: Type .Обратите внимание, что поплавки могут потерять точность.

#!/usr/bin/perl
use warnings;
use strict;

use Cpanel::JSON::XS;
use Cpanel::JSON::XS::Type;

my $type = json_type_arrayof({
    dt      => JSON_TYPE_STRING,
    nt      => JSON_TYPE_INT,
    flt_sm  => JSON_TYPE_FLOAT,
    str     => JSON_TYPE_STRING,
    str_flt => JSON_TYPE_FLOAT,
    flt_lg  => JSON_TYPE_FLOAT,
});


my $data = [{
    dt      => "2018-10-05 09:42:43.483",
    nt      => 1234,
    flt_sm  => ".0123",
    str     => "Hello there",
    str_flt => "0.0123",
    flt_lg  => "10.1234",
}];

my $jsonizer = Cpanel::JSON::XS->new->canonical->pretty;
print $jsonizer->encode($data, $type);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...