perl dbi mysql-值精度

问题描述 投票:0回答:1

user @ host:〜# mysql -V-mysql版本14.14发行版5.7.25-28,用于debian-linux-gnu(x86_64),使用在debian-9,9下运行的7.0

user @ host:〜# uname -a-Linux 4.9.0-8-amd64#1 SMP Debian 4.9.144-3.1(2019-02-19)x86_64 GNU / Linux

user @ host:〜# perl -MDBI -e 'print $DBI::VERSION ."\n";'-1.636

user @ host:〜# perl -v这是为x86_64-linux-gnu-thread-multi构建的perl 5,版本24,版本1(v5.24.1)

mysql> SHOW CREATE TABLE tbl1;

tbl1 |创建表`tbl1`(`id` bigint(20)NOT NULL AUTO_INCREMENT,main_id bigint(20)NOT NULL DEFAULT'0',`debet` varchar(255)NOT NULL DEFAULT``,`kurs` double(20,4)NOT NULL默认'0.0000',sum sum double(20,2)NOT NULL默认值'0.00',is_sync` int(11)NOT NULL默认为'0',主键(`id`),KEY`main_id`(`main_id`))ENGINE = InnoDB AUTO_INCREMENT = 70013000018275 DEFAULT CHARSET = utf8

mysql> SELECT * FROM tbl1 WHERE id=70003020040132;

-+ --------------- + ---------------- + ------- + ------- -+ --------- + --------- +| id | main_id |赌注库尔斯|摘要is_sync |+ ---------------- + ---------------- + ------- + ------- -+ --------- + --------- +| 70003020040132 | 70003020038511 | | 0.0000 | 1798.00 | 0 |+ ---------------- + ---------------- + ------- + ------- -+ --------- + --------- +

但是当我通过perl :: DBI模块获得此数据时,我失去了精度,并且0.00001798.00的值分别变为01798

下一个代码:

#### 
#These 3 subs are connecting to DB, executing query and get data by fetchall_arrayref and coverting undef to NULL.
####
sub DB_connect {
    # DataBase Handler
    my $dbh = DBI->connect("DBI:mysql:$DBNAME", $DBUSER, $DBPWD,{RaiseError => 0, PrintError => 0, mysql_enable_utf8 => 1}) or die "Error connecting to database: $DBI::errstr";
    return $dbh;
}
sub DB_executeQuery {
    # Executes SQL query. Return reference to array, or array, according to argv[0]
    # argv[0] - "A" returns array, "R" - reference to array
    # argv[1] - DB handler from DB_connect
    # argv[2] - query to execute

    my $choice=shift @_;
    my $dbh=shift @_;
    my $query=shift @_;
    print "$query\n" if $DEBUG>2;
    my $sth=$dbh->prepare($query) or die "Error preparing $query for execution: $DBI::errstr";
    $sth->execute;
    my $retval = $sth->fetchall_arrayref;

    if ($choice eq "A" ) {
    my @ret_arr=();
    foreach my $value (@{ $retval }) {
        push @ret_arr,@{ $value };
    }
    return @ret_arr;
    }
    elsif ($choice eq "R") {
    return $retval;
    }
}

sub undef2null {
    # argv[1] - reference ro array of values where undef
    # values has to be changed to NULL
    # Returns array of prepared values: (...) (...) ...
    my $ref=shift @_;
    my @array=();
    foreach my $row (@{ $ref }) {
    my $str="";
    foreach my $val ( @{ $row} ) {
        if (! defined ( $val )) {
        $str="$str, NULL";
        }
        else {
        # Escape quotes and other symbols listed in square brackets
        $val =~ s/([\"\'])/\\$1/g; 
        $str="$str, \'$val\'";
        }
    }
    # Remove ', ' at the beginning of each VALUES substring
    $str=substr($str,2);
    push @array,"($str)";
    } # End foreach my $row (@{ $ref_values })
    return @array;
} # End undef2null

#### Main call
#...
# Somewhere in code I get data from DB and print it to out file
my @arr_values=();
my @arr_col_names=DB_executeQuery("A",$dbh,qq(SELECT column_name FROM `information_schema`.`columns` WHERE `table_schema` = '$DBNAME' AND `table_name` = '@{ $table }'));
@arr_ids=DB_executeQuery("A",$dbh,qq(SELECT `id` FROM `@{ $table }` WHERE `is_sync`=0));
my $ref_values=DB_executeQuery("R",$dbh,"SELECT * FROM \`@{ $table }\` WHERE \`id\` IN(".join(",",@arr_ids).")");
        @arr_values=undef2null($ref_values);
print FOUT  "REPLACE INTO \`@{ $table }\` (`".join("`, `",@arr_col_names)."`) VALUES  ".(join ", ",@arr_values).";\n";

因此,我得到下一个字符串:

替换为`pko_plat`(`id`,`main_id`,`debet`,`kurs`,`summ`,`is_sync`)值('70003020040132','70003020038511','','0',' 1798',“ 0”)

在DB中为0.0000-变为0,为1798.00,变为1798

Perl的DBI文档说,它按原样将数据获取到字符串中,没有进行任何翻译。但是,那么,谁舍入了价值呢?

user @ host:〜#mysql -V-mysql Ver 14.14 Distrib 5.7.25-28,用于debian-linux-gnu(x86_64),使用在debian-9,9下运行的7.0 user @ host:〜#uname -a- Linux 4.9.0-8-amd64#1 SMP Debian 4.9.144-3.1(...

mysql linux perl rounding dbi
1个回答
1
投票

由于创建列的方式,您看到的舍入正在发生。

© www.soinside.com 2019 - 2024. All rights reserved.