2014-11-13 90 views
3

最近我将一个数据库迁移到PostgreSQL,它有一些列定义为numeric(9,3)numeric(9,4)。在测试应用程序时,我发现当数据保存到这些列时,会在插入的值中添加尾随零。我正在使用Hibernate,并且我的日志显示正在为预准备语句构建的正确值。PostgreSQL将尾随零添加到数字

我在插入数据的一个例子是0.75numeric(9,3)列和存储的值是0.750 numeric(9,4)列的另一个示例:我插入值并且DB保存着12.0000

我发现这个相关的问题:postgresql numeric type without trailing zeros。但是它并没有提供一个解决方案,而是引用9.x文档说没有添加尾随零。从这个问题,答案引用文档(我也看过)对此表示:

数字值的物理存储没有任何额外的领先或 尾随零。因此,列 的声明精度和比例是最大值,而不是固定分配。

但是,就像那个问题的海报,我看到尾随的零被添加。由Hibernate在日志中生成的原始插入不会显示此额外行李。所以我认为这是一个PostgreSQL的东西,我没有正确设置,我只是无法找到我错了。

+0

什么是您看到零的客户端?你有没有尝试psql? –

+0

这是一个网络应用程序,我使用Firefox作为我的浏览器。 App Server使用Hibernate在Java中。带有尾部零的“修改”值在实际的DB记录中可见(并且在查询时以这种方式返回到客户端)。 – verbyk1924

+0

您在实际DB记录_中用_visible表示什么意思?客户向你展示什么?我已经问过,你没有回答:你有没有试过psql? –

回答

3

我觉得这是它,如果我理解“要挟”正确地在这方面。这是来自PostgreSQL文档:

可以配置数字列 的最大精度和最大比例。要声明一个数字类型的列,请使用以下语法:

NUMERIC(precision, scale) 

精度必须是正数,比例为零或正数。 或者:

NUMERIC(precision) 

选择0指定的规模:

NUMERIC 

无任何精度或小数创建在 列可以存储其中任何精度和标度的数值,高达 精度的实施限制。这种列不会 强制任何特定比例的输入值,而具有声明比例的数字 列将输入值强制为该比例。

大胆强调我的。

所以这是误导在同一节后面:

数字值的物理存储没有任何多余的领先或 尾随零。因此,列 的声明的精度和规模是最大值,而不是固定分配

再次强调我的意思。

这可能是精确度部分的真实情况,但由于定义的比例被强制定义,因此尾随零将被添加到输入值以符合比例定义(如果比例过大,我会假设截断)。

我正在使用精度,规模限制执行的定义。在数据库插入过程中,尾随零被添加到数字比例中,这似乎支持强制性,并与不添加尾随零的语句冲突。

正确与否,我必须在选择后处理代码中的问题。对我来说幸运的是受影响的属性是BigDecimal,所以剥离尾随零很容易(尽管不是优雅)。如果有人有一个更好的建议,没有PostgreSQL添加尾随零插入数字刻度,我向他们开放。

+0

良好的观察 - 有一个upvote。 –

5

如果您指定一个精度和比例,Pg将按照该精度和比例进行填充。

regress=> SELECT '0'::NUMERIC(8,4); 
numeric 
--------- 
    0.0000 
(1 row) 

没有办法关掉它。它仍然是相同的数字,精度由类型定义,而不是数值。

如果你想拥有的,你必须使用不受约束numeric值定义精度:

regress=> SELECT '0'::NUMERIC, '0.0'::NUMERIC; 
numeric | numeric 
---------+--------- 
     0 |  0.0                                        
(1 row)                                           
+0

PostgreSQL的新特性,所以如果我有一个在数据库中定义为数字(9,4)的列(如下面的num_col),并且我做了一个纯SQL插入(insert into blah(pk,num_col)values(1,12) ;)...我12现在12.0000当我看着它使用SQL或psql或pgAdmin3与选择...(从等等选择num_col;)?规模和精度是在列本身(作为我的限制)上定义的,而不是在我选择期间使用的SQL中。在插入过程中,标尺通过尾随零填充直至达到所定义的限制。对我来说,一个12的插入应该存储12(不是12.0000),并且SQL选择应该返回相同的值? – verbyk1924