Perl,JSON,浮点数,引号

时间:2018-10-05 07:56:47

标签: json perl double-quotes

我们有一个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 :(得分:6)

这就是Cpanel::JSON::XSCpanel::JSON::XS::Type的原因。请注意,浮子可能会失去精度。

use Illuminate\Http\Request;

Route::post('/submit', function (Request $request) {
  $data = $request->validate([
      'title' => 'required|max:255',
      'url' => 'required|url|max:255',
      'description' => 'required|max:255',
  ]);

  $link = tap(new App\Link($data))->save();

  return redirect('/');
});

use App\Link;

Route::delete('/link/{link}', function (Link $link) {
  // Link::destroy($link);
  $link->delete();
  return redirect('/');
});

Route::PUT('/link/{link}', function (Link $link) {
  $link->update();
  return redirect('/');
});

答案 1 :(得分:0)

尝试类似的方法,将数字字段加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;
}
...