我们正在将值插入到Perl的NUMERIC(19,5)类型的SQL Server 2005数据库列中。只要绝对值为.0001或更高,它就可以工作。但是,当值到达第5个小数位时,Perl开始以指数格式(-9e-05
而不是-0.00009
)存储它们,然后我们从SQL Server获得错误“Error converting data type varchar to numeric
” 。我们如何防止这种情况并使其正确插入小数值?
我们使用的是perl v5.8.5,DBI 1.56,DBD :: Sybase 1.07和SQL Server 2005.
代码大致如下,但我删除了无关的字段:
$invoice->{IL_UNITPRICE} = 0.09; # Actually comes from another database
$invoice->{IL_PRICEUNITCONV} = 0.001; # Actually comes from another database
$unitprice = $invoice->{IL_UNITPRICE} * -1 * $invoice->{IL_PRICEUNITCONV};
#$unitprice equals -9e-05 at this point.
$sth = $dbh->prepare('INSERT INTO foo ( bar ) VALUES ( ? )');
$sth->execute($unitprice);
上述行失败,错误为:DBD::Sybase::st execute failed: Server message number=8114 severity=16 state=5 line=2 server=baz text=Error converting data type varchar to numeric.
答案 0 :(得分:2)
尝试
$sth->execute(sprintf("%.6f",$unitprice));
扩展一点 - 当您通过DBi接口传递本机float / double时,它会转换为字符串,如果您没有另外指定,则使用Perl的默认格式约定(由C编译器强加) 。默认值为6位精度,如果数字超过了数字,则以科学计数法表示。
要获得定点格式,您必须使用sprintf明确要求它。
答案 1 :(得分:0)
实际上我认为使用Math::Bigint及其相关的Math :: BigFloat也可以解决这个问题。每当我使用浮点数或足够大的数字时,我都会使用这些模块,因此除非我真的想控制格式化,否则我不必将sprintf扔到所有地方。